| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2016 Edouard Griffiths, F4EXB                                   //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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 <QUdpSocket>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include <QTimer>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "dsp/dspcommands.h"
 | 
					
						
							|  |  |  | #include "dsp/dspengine.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-11 01:17:55 +02:00
										 |  |  | #include <device/devicesourceapi.h>
 | 
					
						
							| 
									
										
										
										
											2017-06-09 13:58:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "sdrdaemonsourceinput.h"
 | 
					
						
							|  |  |  | #include "sdrdaemonsourceudphandler.h"
 | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | SDRdaemonSourceUDPHandler::SDRdaemonSourceUDPHandler(SampleSinkFifo *sampleFifo, DeviceSourceAPI *deviceAPI) : | 
					
						
							|  |  |  |     m_deviceAPI(deviceAPI), | 
					
						
							|  |  |  |     m_masterTimer(deviceAPI->getMasterTimer()), | 
					
						
							|  |  |  |     m_masterTimerConnected(false), | 
					
						
							|  |  |  |     m_running(false), | 
					
						
							| 
									
										
										
										
											2018-02-24 10:29:27 +01:00
										 |  |  |     m_rateDivider(1000/SDRDAEMONSOURCE_THROTTLE_MS), | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	m_dataSocket(0), | 
					
						
							|  |  |  | 	m_dataAddress(QHostAddress::LocalHost), | 
					
						
							|  |  |  | 	m_remoteAddress(QHostAddress::LocalHost), | 
					
						
							|  |  |  | 	m_dataPort(9090), | 
					
						
							|  |  |  | 	m_dataConnected(false), | 
					
						
							|  |  |  | 	m_udpBuf(0), | 
					
						
							|  |  |  | 	m_udpReadBytes(0), | 
					
						
							|  |  |  | 	m_sampleFifo(sampleFifo), | 
					
						
							|  |  |  | 	m_samplerate(0), | 
					
						
							|  |  |  | 	m_centerFrequency(0), | 
					
						
							|  |  |  | 	m_tv_sec(0), | 
					
						
							|  |  |  | 	m_tv_usec(0), | 
					
						
							| 
									
										
										
										
											2017-12-24 19:58:26 +01:00
										 |  |  | 	m_outputMessageQueueToGUI(0), | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	m_tickCount(0), | 
					
						
							|  |  |  | 	m_samplesCount(0), | 
					
						
							|  |  |  | 	m_timer(0), | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  |     m_throttlems(SDRDAEMONSOURCE_THROTTLE_MS), | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  |     m_readLengthSamples(0), | 
					
						
							|  |  |  |     m_readLength(0), | 
					
						
							| 
									
										
										
										
											2018-01-24 08:49:18 +01:00
										 |  |  |     m_converterBuffer(0), | 
					
						
							|  |  |  |     m_converterBufferNbSamples(0), | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  |     m_throttleToggle(false), | 
					
						
							| 
									
										
										
										
											2016-07-12 08:52:38 +02:00
										 |  |  | 	m_autoCorrBuffer(true) | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  |     m_udpBuf = new char[SDRdaemonSourceBuffer::m_udpPayloadSize]; | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_INTERNAL_TIMER
 | 
					
						
							|  |  |  | #warning "Uses internal timer"
 | 
					
						
							|  |  |  |     m_timer = new QTimer(); | 
					
						
							|  |  |  |     m_timer->start(50); | 
					
						
							|  |  |  |     m_throttlems = m_timer->interval(); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     m_throttlems = m_masterTimer.interval(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     m_rateDivider = 1000 / m_throttlems; | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | SDRdaemonSourceUDPHandler::~SDRdaemonSourceUDPHandler() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	stop(); | 
					
						
							|  |  |  | 	delete[] m_udpBuf; | 
					
						
							| 
									
										
										
										
											2018-01-24 08:49:18 +01:00
										 |  |  | 	if (m_converterBuffer) { delete[] m_converterBuffer; } | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | #ifdef USE_INTERNAL_TIMER
 | 
					
						
							|  |  |  |     if (m_timer) { | 
					
						
							|  |  |  |         delete m_timer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | void SDRdaemonSourceUDPHandler::start() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-09 14:18:11 +02:00
										 |  |  | 	qDebug("SDRdaemonSourceUDPHandler::start"); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 	if (m_running) { | 
					
						
							|  |  |  | 	    return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	if (!m_dataSocket) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_dataSocket = new QUdpSocket(this); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 08:20:53 +01:00
										 |  |  |     if (!m_dataConnected) | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-09 09:57:26 +02:00
										 |  |  |         connect(m_dataSocket, SIGNAL(readyRead()), this, SLOT(dataReadyRead())); //, Qt::QueuedConnection);
 | 
					
						
							| 
									
										
										
										
											2017-02-03 08:20:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (m_dataSocket->bind(m_dataAddress, m_dataPort)) | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-06-09 14:18:11 +02:00
										 |  |  | 			qDebug("SDRdaemonSourceUDPHandler::start: bind data socket to %s:%d", m_dataAddress.toString().toStdString().c_str(),  m_dataPort); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 			m_dataConnected = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-06-09 14:18:11 +02:00
										 |  |  | 			qWarning("SDRdaemonSourceUDPHandler::start: cannot bind data port %d", m_dataPort); | 
					
						
							| 
									
										
										
										
											2017-02-03 08:20:53 +01:00
										 |  |  | 	        disconnect(m_dataSocket, SIGNAL(readyRead()), this, SLOT(dataReadyRead())); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 			m_dataConnected = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_elapsedTimer.start(); | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |     m_running = true; | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | void SDRdaemonSourceUDPHandler::stop() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-09 14:18:11 +02:00
										 |  |  | 	qDebug("SDRdaemonSourceUDPHandler::stop"); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 	if (!m_running) { | 
					
						
							|  |  |  | 	    return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	disconnectTimer(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 08:20:53 +01:00
										 |  |  |     if (m_dataConnected) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 		m_dataConnected = false; | 
					
						
							| 
									
										
										
										
											2017-02-03 08:20:53 +01:00
										 |  |  | 	    disconnect(m_dataSocket, SIGNAL(readyRead()), this, SLOT(dataReadyRead())); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (m_dataSocket) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		delete m_dataSocket; | 
					
						
							|  |  |  | 		m_dataSocket = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-12-25 09:10:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 	m_centerFrequency = 0; | 
					
						
							|  |  |  | 	m_samplerate = 0; | 
					
						
							|  |  |  | 	m_running = false; | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | void SDRdaemonSourceUDPHandler::configureUDPLink(const QString& address, quint16 port) | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-09 14:18:11 +02:00
										 |  |  | 	qDebug("SDRdaemonSourceUDPHandler::configureUDPLink: %s:%d", address.toStdString().c_str(), port); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	bool addressOK = m_dataAddress.setAddress(address); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!addressOK) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-06-09 14:18:11 +02:00
										 |  |  | 		qWarning("SDRdaemonSourceUDPHandler::configureUDPLink: invalid address %s. Set to localhost.", address.toStdString().c_str()); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 		m_dataAddress = QHostAddress::LocalHost; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_dataPort = port; | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 	stop(); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	start(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | void SDRdaemonSourceUDPHandler::dataReadyRead() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-07-12 04:44:44 +02:00
										 |  |  |     m_udpReadBytes = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-29 08:21:27 +02:00
										 |  |  | 	while (m_dataSocket->hasPendingDatagrams() && m_dataConnected) | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		qint64 pendingDataSize = m_dataSocket->pendingDatagramSize(); | 
					
						
							| 
									
										
										
										
											2016-07-12 04:44:44 +02:00
										 |  |  | 		m_udpReadBytes += m_dataSocket->readDatagram(&m_udpBuf[m_udpReadBytes], pendingDataSize, &m_remoteAddress, 0); | 
					
						
							| 
									
										
										
										
											2016-06-20 00:45:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | 		if (m_udpReadBytes == SDRdaemonSourceBuffer::m_udpPayloadSize) { | 
					
						
							| 
									
										
										
										
											2016-06-20 00:45:24 +02:00
										 |  |  | 		    processData(); | 
					
						
							| 
									
										
										
										
											2016-07-12 04:44:44 +02:00
										 |  |  | 		    m_udpReadBytes = 0; | 
					
						
							| 
									
										
										
										
											2016-06-20 00:45:24 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | void SDRdaemonSourceUDPHandler::processData() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-05-25 20:13:34 +02:00
										 |  |  |     m_sdrDaemonBuffer.writeData(m_udpBuf); | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  |     const SDRdaemonSourceBuffer::MetaDataFEC& metaData =  m_sdrDaemonBuffer.getCurrentMeta(); | 
					
						
							| 
									
										
										
										
											2016-06-20 09:07:37 +02:00
										 |  |  |     bool change = false; | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-24 12:53:39 +02:00
										 |  |  |     m_tv_sec = m_sdrDaemonBuffer.getTVOutSec(); | 
					
						
							|  |  |  |     m_tv_usec = m_sdrDaemonBuffer.getTVOutUsec(); | 
					
						
							| 
									
										
										
										
											2016-06-20 09:07:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (m_centerFrequency != metaData.m_centerFrequency) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_centerFrequency = metaData.m_centerFrequency; | 
					
						
							|  |  |  |         change = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_samplerate != metaData.m_sampleRate) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_samplerate = metaData.m_sampleRate; | 
					
						
							|  |  |  |         change = true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |     if (change && (m_samplerate != 0) && (m_centerFrequency != 0)) | 
					
						
							| 
									
										
										
										
											2016-06-20 09:07:37 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-12-25 09:10:19 +01:00
										 |  |  |         qDebug("SDRdaemonSourceUDPHandler::processData: m_samplerate: %u m_centerFrequency: %u kHz", m_samplerate, m_centerFrequency); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |         DSPSignalNotification *notif = new DSPSignalNotification(m_samplerate, m_centerFrequency * 1000); // Frequency in Hz for the DSP engine
 | 
					
						
							|  |  |  |         m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_outputMessageQueueToGUI) | 
					
						
							| 
									
										
										
										
											2017-12-25 09:10:19 +01:00
										 |  |  |         { | 
					
						
							|  |  |  |             SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData *report = SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamData::create( | 
					
						
							|  |  |  |                 m_samplerate, | 
					
						
							|  |  |  |                 m_centerFrequency * 1000, // Frequency in Hz for the GUI
 | 
					
						
							|  |  |  |                 m_tv_sec, | 
					
						
							|  |  |  |                 m_tv_usec); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_outputMessageQueueToGUI->push(report); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         connectTimer(); | 
					
						
							| 
									
										
										
										
											2016-06-20 09:07:37 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | void SDRdaemonSourceUDPHandler::connectTimer() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |     if (!m_masterTimerConnected) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "SDRdaemonSourceUDPHandler::connectTimer"; | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | #ifdef USE_INTERNAL_TIMER
 | 
					
						
							|  |  |  | #warning "Uses internal timer"
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |         connect(m_timer, SIGNAL(timeout()), this, SLOT(tick())); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |         connect(&m_masterTimer, SIGNAL(timeout()), this, SLOT(tick())); | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  |         m_masterTimerConnected = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SDRdaemonSourceUDPHandler::disconnectTimer() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_masterTimerConnected) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "SDRdaemonSourceUDPHandler::disconnectTimer"; | 
					
						
							|  |  |  | #ifdef USE_INTERNAL_TIMER
 | 
					
						
							|  |  |  | #warning "Uses internal timer"
 | 
					
						
							|  |  |  |         disconnect(m_timer, SIGNAL(timeout()), this, SLOT(tick())); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         disconnect(&m_masterTimer, SIGNAL(timeout()), this, SLOT(tick())); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         m_masterTimerConnected = false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  | void SDRdaemonSourceUDPHandler::tick() | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     // auto throttling
 | 
					
						
							|  |  |  |     int throttlems = m_elapsedTimer.restart(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (throttlems != m_throttlems) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_throttlems = throttlems; | 
					
						
							| 
									
										
										
										
											2016-06-20 01:32:32 +02:00
										 |  |  |         m_readLengthSamples = (m_sdrDaemonBuffer.getCurrentMeta().m_sampleRate * (m_throttlems+(m_throttleToggle ? 1 : 0))) / 1000; | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  |         m_throttleToggle = !m_throttleToggle; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-13 03:31:19 +02:00
										 |  |  |     if (m_autoCorrBuffer) { | 
					
						
							|  |  |  |         m_readLengthSamples += m_sdrDaemonBuffer.getRWBalanceCorrection(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-09 14:14:32 +02:00
										 |  |  |     m_readLength = m_readLengthSamples * SDRdaemonSourceBuffer::m_iqSampleSize; | 
					
						
							| 
									
										
										
										
											2016-07-13 03:31:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-24 08:49:18 +01:00
										 |  |  |     if (SDR_RX_SAMP_SZ == 16) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // read samples directly feeding the SampleFifo (no callback)
 | 
					
						
							|  |  |  |         m_sampleFifo->write(reinterpret_cast<quint8*>(m_sdrDaemonBuffer.readData(m_readLength)), m_readLength); | 
					
						
							|  |  |  |         m_samplesCount += m_readLengthSamples; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (SDR_RX_SAMP_SZ == 24) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (m_readLengthSamples > m_converterBufferNbSamples) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (m_converterBuffer) { delete[] m_converterBuffer; } | 
					
						
							|  |  |  |             m_converterBuffer = new int32_t[m_readLengthSamples*2]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         uint8_t *buf = m_sdrDaemonBuffer.readData(m_readLength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (unsigned int is = 0; is < m_readLengthSamples; is++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_converterBuffer[2*is] = ((int16_t*)buf)[2*is]; | 
					
						
							|  |  |  |             m_converterBuffer[2*is]<<=8; | 
					
						
							|  |  |  |             m_converterBuffer[2*is+1] = ((int16_t*)buf)[2*is+1]; | 
					
						
							|  |  |  |             m_converterBuffer[2*is+1]<<=8; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 18:39:04 +01:00
										 |  |  |         m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample)); | 
					
						
							| 
									
										
										
										
											2018-01-24 08:49:18 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (m_tickCount < m_rateDivider) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_tickCount++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_tickCount = 0; | 
					
						
							| 
									
										
										
										
											2016-07-24 11:09:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-24 19:58:26 +01:00
										 |  |  | 		if (m_outputMessageQueueToGUI) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-12-26 02:18:30 +01:00
										 |  |  | 	        int framesDecodingStatus; | 
					
						
							|  |  |  | 	        int minNbBlocks = m_sdrDaemonBuffer.getMinNbBlocks(); | 
					
						
							|  |  |  | 	        int minNbOriginalBlocks = m_sdrDaemonBuffer.getMinOriginalBlocks(); | 
					
						
							|  |  |  | 	        int nbOriginalBlocks = m_sdrDaemonBuffer.getCurrentMeta().m_nbOriginalBlocks; | 
					
						
							|  |  |  | 	        int nbFECblocks = m_sdrDaemonBuffer.getCurrentMeta().m_nbFECBlocks; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	        //framesDecodingStatus = (minNbOriginalBlocks == nbOriginalBlocks ? 2 : (minNbOriginalBlocks < nbOriginalBlocks - nbFECblocks ? 0 : 1));
 | 
					
						
							|  |  |  | 	        if (minNbBlocks < nbOriginalBlocks) { | 
					
						
							|  |  |  | 	            framesDecodingStatus = 0; | 
					
						
							|  |  |  | 	        } else if (minNbBlocks < nbOriginalBlocks + nbFECblocks) { | 
					
						
							|  |  |  | 	            framesDecodingStatus = 1; | 
					
						
							|  |  |  | 	        } else { | 
					
						
							|  |  |  | 	            framesDecodingStatus = 2; | 
					
						
							|  |  |  | 	        } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-24 19:58:26 +01:00
										 |  |  | 	        SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming *report = SDRdaemonSourceInput::MsgReportSDRdaemonSourceStreamTiming::create( | 
					
						
							|  |  |  | 	            m_tv_sec, | 
					
						
							|  |  |  | 	            m_tv_usec, | 
					
						
							|  |  |  | 	            m_sdrDaemonBuffer.getBufferLengthInSecs(), | 
					
						
							|  |  |  | 	            m_sdrDaemonBuffer.getBufferGauge(), | 
					
						
							|  |  |  | 	            framesDecodingStatus, | 
					
						
							|  |  |  | 	            minNbBlocks == nbOriginalBlocks + nbFECblocks, | 
					
						
							|  |  |  | 	            minNbBlocks, | 
					
						
							|  |  |  | 	            minNbOriginalBlocks, | 
					
						
							|  |  |  | 	            m_sdrDaemonBuffer.getMaxNbRecovery(), | 
					
						
							|  |  |  | 	            m_sdrDaemonBuffer.getAvgNbBlocks(), | 
					
						
							|  |  |  | 	            m_sdrDaemonBuffer.getAvgOriginalBlocks(), | 
					
						
							|  |  |  | 	            m_sdrDaemonBuffer.getAvgNbRecovery(), | 
					
						
							|  |  |  | 	            nbOriginalBlocks, | 
					
						
							|  |  |  | 	            nbFECblocks); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	            m_outputMessageQueueToGUI->push(report); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-19 09:56:49 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } |