Rename SDRDaemonSink device plugin to RemoteOutput (1)

pull/295/head
f4exb 2019-02-02 22:58:42 +01:00
rodzic 8ccab8acf4
commit ad66b4af49
52 zmienionych plików z 627 dodań i 620 usunięć

Wyświetl plik

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 34 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 34 KiB

Wyświetl plik

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 7.3 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 7.3 KiB

Wyświetl plik

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 8.0 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 8.0 KiB

Wyświetl plik

@ -94,7 +94,7 @@ RemoteSink::~RemoteSink()
void RemoteSink::setTxDelay(int txDelay, int nbBlocksFEC) void RemoteSink::setTxDelay(int txDelay, int nbBlocksFEC)
{ {
double txDelayRatio = txDelay / 100.0; double txDelayRatio = txDelay / 100.0;
int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); int samplesPerBlock = RemoteNbBytesPerBlock / sizeof(Sample);
double delay = m_sampleRate == 0 ? 1.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate; double delay = m_sampleRate == 0 ? 1.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate;
delay /= 128 + nbBlocksFEC; delay /= 128 + nbBlocksFEC;
m_txDelay = roundf(delay*1e6); // microseconds m_txDelay = roundf(delay*1e6); // microseconds
@ -123,35 +123,34 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
if (m_txBlockIndex == 0) if (m_txBlockIndex == 0)
{ {
struct timeval tv; struct timeval tv;
SDRDaemonMetaDataFEC metaData; RemoteMetaDataFEC metaData;
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
metaData.m_centerFrequency = m_centerFrequency; metaData.m_centerFrequency = m_centerFrequency;
metaData.m_sampleRate = m_sampleRate; metaData.m_sampleRate = m_sampleRate;
metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
metaData.m_sampleBits = SDR_RX_SAMP_SZ; metaData.m_sampleBits = SDR_RX_SAMP_SZ;
metaData.m_nbOriginalBlocks = SDRDaemonNbOrginalBlocks; metaData.m_nbOriginalBlocks = RemoteNbOrginalBlocks;
metaData.m_nbFECBlocks = m_nbBlocksFEC; metaData.m_nbFECBlocks = m_nbBlocksFEC;
metaData.m_tv_sec = tv.tv_sec; metaData.m_tv_sec = tv.tv_sec;
metaData.m_tv_usec = tv.tv_usec; metaData.m_tv_usec = tv.tv_usec;
if (!m_dataBlock) { // on the very first cycle there is no data block allocated if (!m_dataBlock) { // on the very first cycle there is no data block allocated
m_dataBlock = new SDRDaemonDataBlock(); m_dataBlock = new RemoteDataBlock();
} }
boost::crc_32_type crc32; boost::crc_32_type crc32;
crc32.process_bytes(&metaData, 20); crc32.process_bytes(&metaData, 20);
metaData.m_crc32 = crc32.checksum(); metaData.m_crc32 = crc32.checksum();
SDRDaemonSuperBlock& superBlock = m_dataBlock->m_superBlocks[0]; // first block RemoteSuperBlock& superBlock = m_dataBlock->m_superBlocks[0]; // first block
superBlock.init(); superBlock.init();
superBlock.m_header.m_frameIndex = m_frameCount; superBlock.m_header.m_frameIndex = m_frameCount;
superBlock.m_header.m_blockIndex = m_txBlockIndex; superBlock.m_header.m_blockIndex = m_txBlockIndex;
superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ;
SDRDaemonMetaDataFEC *destMeta = (SDRDaemonMetaDataFEC *) &superBlock.m_protectedBlock; RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &superBlock.m_protectedBlock;
*destMeta = metaData; *destMeta = metaData;
//memcpy((void *) &superBlock.m_protectedBlock, (const void *) &metaData, sizeof(SDRDaemonMetaDataFEC));
if (!(metaData == m_currentMetaFEC)) if (!(metaData == m_currentMetaFEC))
{ {
@ -172,7 +171,7 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
} // block zero } // block zero
// handle different sample sizes... // handle different sample sizes...
int samplesPerBlock = SDRDaemonNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); // two I or Q samples int samplesPerBlock = RemoteNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); // two I or Q samples
if (m_sampleIndex + inRemainingSamples < samplesPerBlock) // there is still room in the current super block if (m_sampleIndex + inRemainingSamples < samplesPerBlock) // there is still room in the current super block
{ {
memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)],
@ -195,7 +194,7 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ;
m_dataBlock->m_superBlocks[m_txBlockIndex] = m_superBlock; m_dataBlock->m_superBlocks[m_txBlockIndex] = m_superBlock;
if (m_txBlockIndex == SDRDaemonNbOrginalBlocks - 1) // frame complete if (m_txBlockIndex == RemoteNbOrginalBlocks - 1) // frame complete
{ {
m_dataBlockMutex.lock(); m_dataBlockMutex.lock();
m_dataBlock->m_txControlBlock.m_frameIndex = m_frameCount; m_dataBlock->m_txControlBlock.m_frameIndex = m_frameCount;
@ -207,7 +206,7 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
m_dataBlock->m_txControlBlock.m_dataPort = m_dataPort; m_dataBlock->m_txControlBlock.m_dataPort = m_dataPort;
emit dataBlockAvailable(m_dataBlock); emit dataBlockAvailable(m_dataBlock);
m_dataBlock = new SDRDaemonDataBlock(); // create a new one immediately m_dataBlock = new RemoteDataBlock(); // create a new one immediately
m_dataBlockMutex.unlock(); m_dataBlockMutex.unlock();
m_txBlockIndex = 0; m_txBlockIndex = 0;
@ -225,7 +224,7 @@ void RemoteSink::start()
{ {
qDebug("RemoteSink::start"); qDebug("RemoteSink::start");
memset((void *) &m_currentMetaFEC, 0, sizeof(SDRDaemonMetaDataFEC)); memset((void *) &m_currentMetaFEC, 0, sizeof(RemoteMetaDataFEC));
if (m_running) { if (m_running) {
stop(); stop();
@ -233,9 +232,9 @@ void RemoteSink::start()
m_sinkThread = new RemoteSinkThread(); m_sinkThread = new RemoteSinkThread();
connect(this, connect(this,
SIGNAL(dataBlockAvailable(SDRDaemonDataBlock *)), SIGNAL(dataBlockAvailable(RemoteDataBlock *)),
m_sinkThread, m_sinkThread,
SLOT(processDataBlock(SDRDaemonDataBlock *)), SLOT(processDataBlock(RemoteDataBlock *)),
Qt::QueuedConnection); Qt::QueuedConnection);
m_sinkThread->startStop(true); m_sinkThread->startStop(true);
m_running = true; m_running = true;

Wyświetl plik

@ -23,14 +23,13 @@
#ifndef INCLUDE_REMOTESINK_H_ #ifndef INCLUDE_REMOTESINK_H_
#define INCLUDE_REMOTESINK_H_ #define INCLUDE_REMOTESINK_H_
#include <channel/remotedatablock.h>
#include <QObject> #include <QObject>
#include <QMutex> #include <QMutex>
#include <QNetworkRequest> #include <QNetworkRequest>
#include "dsp/basebandsamplesink.h" #include "dsp/basebandsamplesink.h"
#include "channel/channelsinkapi.h" #include "channel/channelsinkapi.h"
#include "channel/sdrdaemondatablock.h"
#include "../remotesink/remotesinksettings.h" #include "../remotesink/remotesinksettings.h"
class QNetworkAccessManager; class QNetworkAccessManager;
@ -127,7 +126,7 @@ public:
static const QString m_channelId; static const QString m_channelId;
signals: signals:
void dataBlockAvailable(SDRDaemonDataBlock *dataBlock); void dataBlockAvailable(RemoteDataBlock *dataBlock);
private: private:
DeviceSourceAPI *m_deviceAPI; DeviceSourceAPI *m_deviceAPI;
@ -141,9 +140,9 @@ private:
int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row
uint16_t m_frameCount; //!< transmission frame count uint16_t m_frameCount; //!< transmission frame count
int m_sampleIndex; //!< Current sample index in protected block data int m_sampleIndex; //!< Current sample index in protected block data
SDRDaemonSuperBlock m_superBlock; RemoteSuperBlock m_superBlock;
SDRDaemonMetaDataFEC m_currentMetaFEC; RemoteMetaDataFEC m_currentMetaFEC;
SDRDaemonDataBlock *m_dataBlock; RemoteDataBlock *m_dataBlock;
QMutex m_dataBlockMutex; QMutex m_dataBlockMutex;
uint64_t m_centerFrequency; uint64_t m_centerFrequency;

Wyświetl plik

@ -304,7 +304,7 @@ void RemoteSinkGUI::on_nbFECBlocks_valueChanged(int value)
void RemoteSinkGUI::updateTxDelayTime() void RemoteSinkGUI::updateTxDelayTime()
{ {
double txDelayRatio = m_settings.m_txDelay / 100.0; double txDelayRatio = m_settings.m_txDelay / 100.0;
int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); int samplesPerBlock = RemoteNbBytesPerBlock / sizeof(Sample);
double delay = m_sampleRate == 0 ? 0.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate; double delay = m_sampleRate == 0 ? 0.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate;
delay /= 128 + m_settings.m_nbFECBlocks; delay /= 128 + m_settings.m_nbFECBlocks;
ui->txDelayTime->setText(tr("%1µs").arg(QString::number(delay*1e6, 'f', 0))); ui->txDelayTime->setText(tr("%1µs").arg(QString::number(delay*1e6, 'f', 0)));

Wyświetl plik

@ -22,9 +22,9 @@
#include "remotesinkthread.h" #include "remotesinkthread.h"
#include <channel/remotedatablock.h>
#include <QUdpSocket> #include <QUdpSocket>
#include "channel/sdrdaemondatablock.h"
#include "cm256.h" #include "cm256.h"
MESSAGE_CLASS_DEFINITION(RemoteSinkThread::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(RemoteSinkThread::MsgStartStop, Message)
@ -86,48 +86,48 @@ void RemoteSinkThread::run()
qDebug("RemoteSinkThread::run: end"); qDebug("RemoteSinkThread::run: end");
} }
void RemoteSinkThread::processDataBlock(SDRDaemonDataBlock *dataBlock) void RemoteSinkThread::processDataBlock(RemoteDataBlock *dataBlock)
{ {
handleDataBlock(*dataBlock); handleDataBlock(*dataBlock);
delete dataBlock; delete dataBlock;
} }
void RemoteSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock) void RemoteSinkThread::handleDataBlock(RemoteDataBlock& dataBlock)
{ {
CM256::cm256_encoder_params cm256Params; //!< Main interface with CM256 encoder CM256::cm256_encoder_params cm256Params; //!< Main interface with CM256 encoder
CM256::cm256_block descriptorBlocks[256]; //!< Pointers to data for CM256 encoder CM256::cm256_block descriptorBlocks[256]; //!< Pointers to data for CM256 encoder
SDRDaemonProtectedBlock fecBlocks[256]; //!< FEC data RemoteProtectedBlock fecBlocks[256]; //!< FEC data
uint16_t frameIndex = dataBlock.m_txControlBlock.m_frameIndex; uint16_t frameIndex = dataBlock.m_txControlBlock.m_frameIndex;
int nbBlocksFEC = dataBlock.m_txControlBlock.m_nbBlocksFEC; int nbBlocksFEC = dataBlock.m_txControlBlock.m_nbBlocksFEC;
int txDelay = dataBlock.m_txControlBlock.m_txDelay; int txDelay = dataBlock.m_txControlBlock.m_txDelay;
m_address.setAddress(dataBlock.m_txControlBlock.m_dataAddress); m_address.setAddress(dataBlock.m_txControlBlock.m_dataAddress);
uint16_t dataPort = dataBlock.m_txControlBlock.m_dataPort; uint16_t dataPort = dataBlock.m_txControlBlock.m_dataPort;
SDRDaemonSuperBlock *txBlockx = dataBlock.m_superBlocks; RemoteSuperBlock *txBlockx = dataBlock.m_superBlocks;
if ((nbBlocksFEC == 0) || !m_cm256p) // Do not FEC encode if ((nbBlocksFEC == 0) || !m_cm256p) // Do not FEC encode
{ {
if (m_socket) if (m_socket)
{ {
for (int i = 0; i < SDRDaemonNbOrginalBlocks; i++) for (int i = 0; i < RemoteNbOrginalBlocks; i++)
{ {
// send block via UDP // send block via UDP
m_socket->writeDatagram((const char*)&txBlockx[i], (qint64 ) SDRDaemonUdpSize, m_address, dataPort); m_socket->writeDatagram((const char*)&txBlockx[i], (qint64 ) RemoteUdpSize, m_address, dataPort);
usleep(txDelay); usleep(txDelay);
} }
} }
} }
else else
{ {
cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock); cm256Params.BlockBytes = sizeof(RemoteProtectedBlock);
cm256Params.OriginalCount = SDRDaemonNbOrginalBlocks; cm256Params.OriginalCount = RemoteNbOrginalBlocks;
cm256Params.RecoveryCount = nbBlocksFEC; cm256Params.RecoveryCount = nbBlocksFEC;
// Fill pointers to data // Fill pointers to data
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i) for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i)
{ {
if (i >= cm256Params.OriginalCount) { if (i >= cm256Params.OriginalCount) {
memset((void *) &txBlockx[i].m_protectedBlock, 0, sizeof(SDRDaemonProtectedBlock)); memset((void *) &txBlockx[i].m_protectedBlock, 0, sizeof(RemoteProtectedBlock));
} }
txBlockx[i].m_header.m_frameIndex = frameIndex; txBlockx[i].m_header.m_frameIndex = frameIndex;
@ -157,7 +157,7 @@ void RemoteSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock)
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++) for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
{ {
// send block via UDP // send block via UDP
m_socket->writeDatagram((const char*)&txBlockx[i], (qint64 ) SDRDaemonUdpSize, m_address, dataPort); m_socket->writeDatagram((const char*)&txBlockx[i], (qint64 ) RemoteUdpSize, m_address, dataPort);
usleep(txDelay); usleep(txDelay);
} }
} }

Wyświetl plik

@ -33,7 +33,7 @@
#include "util/message.h" #include "util/message.h"
#include "util/messagequeue.h" #include "util/messagequeue.h"
class SDRDaemonDataBlock; class RemoteDataBlock;
class CM256; class CM256;
class QUdpSocket; class QUdpSocket;
@ -66,7 +66,7 @@ public:
void startStop(bool start); void startStop(bool start);
public slots: public slots:
void processDataBlock(SDRDaemonDataBlock *dataBlock); void processDataBlock(RemoteDataBlock *dataBlock);
private: private:
QMutex m_startWaitMutex; QMutex m_startWaitMutex;
@ -85,7 +85,7 @@ private:
void stopWork(); void stopWork();
void run(); void run();
void handleDataBlock(SDRDaemonDataBlock& dataBlock); void handleDataBlock(RemoteDataBlock& dataBlock);
private slots: private slots:
void handleInputMessages(); void handleInputMessages();

Wyświetl plik

@ -243,10 +243,10 @@ void RemoteSource::applySettings(const RemoteSourceSettings& settings, bool forc
m_settings = settings; m_settings = settings;
} }
void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock) void RemoteSource::handleDataBlock(RemoteDataBlock* dataBlock)
{ {
(void) dataBlock; (void) dataBlock;
if (dataBlock->m_rxControlBlock.m_blockCount < SDRDaemonNbOrginalBlocks) if (dataBlock->m_rxControlBlock.m_blockCount < RemoteNbOrginalBlocks)
{ {
qWarning("RemoteSource::handleDataBlock: incomplete data block: not processing"); qWarning("RemoteSource::handleDataBlock: incomplete data block: not processing");
} }
@ -270,15 +270,15 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
} }
} }
//qDebug("DaemonSource::handleDataBlock: frame: %u blocks: %d", dataBlock.m_rxControlBlock.m_frameIndex, blockCount); //qDebug("RemoteSource::handleDataBlock: frame: %u blocks: %d", dataBlock.m_rxControlBlock.m_frameIndex, blockCount);
// Need to use the CM256 recovery // Need to use the CM256 recovery
if (m_cm256p &&(dataBlock->m_rxControlBlock.m_originalCount < SDRDaemonNbOrginalBlocks)) if (m_cm256p &&(dataBlock->m_rxControlBlock.m_originalCount < RemoteNbOrginalBlocks))
{ {
qDebug("RemoteSource::handleDataBlock: %d recovery blocks", dataBlock->m_rxControlBlock.m_recoveryCount); qDebug("RemoteSource::handleDataBlock: %d recovery blocks", dataBlock->m_rxControlBlock.m_recoveryCount);
CM256::cm256_encoder_params paramsCM256; CM256::cm256_encoder_params paramsCM256;
paramsCM256.BlockBytes = sizeof(SDRDaemonProtectedBlock); // never changes paramsCM256.BlockBytes = sizeof(RemoteProtectedBlock); // never changes
paramsCM256.OriginalCount = SDRDaemonNbOrginalBlocks; // never changes paramsCM256.OriginalCount = RemoteNbOrginalBlocks; // never changes
if (m_currentMeta.m_tv_sec == 0) { if (m_currentMeta.m_tv_sec == 0) {
paramsCM256.RecoveryCount = dataBlock->m_rxControlBlock.m_recoveryCount; paramsCM256.RecoveryCount = dataBlock->m_rxControlBlock.m_recoveryCount;
@ -287,8 +287,8 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
} }
// update counters // update counters
if (dataBlock->m_rxControlBlock.m_originalCount < SDRDaemonNbOrginalBlocks - paramsCM256.RecoveryCount) { if (dataBlock->m_rxControlBlock.m_originalCount < RemoteNbOrginalBlocks - paramsCM256.RecoveryCount) {
m_nbUncorrectableErrors += SDRDaemonNbOrginalBlocks - paramsCM256.RecoveryCount - dataBlock->m_rxControlBlock.m_originalCount; m_nbUncorrectableErrors += RemoteNbOrginalBlocks - paramsCM256.RecoveryCount - dataBlock->m_rxControlBlock.m_originalCount;
} else { } else {
m_nbCorrectableErrors += dataBlock->m_rxControlBlock.m_recoveryCount; m_nbCorrectableErrors += dataBlock->m_rxControlBlock.m_recoveryCount;
} }
@ -303,11 +303,11 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
{ {
for (int ir = 0; ir < dataBlock->m_rxControlBlock.m_recoveryCount; ir++) // restore missing blocks for (int ir = 0; ir < dataBlock->m_rxControlBlock.m_recoveryCount; ir++) // restore missing blocks
{ {
int recoveryIndex = SDRDaemonNbOrginalBlocks - dataBlock->m_rxControlBlock.m_recoveryCount + ir; int recoveryIndex = RemoteNbOrginalBlocks - dataBlock->m_rxControlBlock.m_recoveryCount + ir;
int blockIndex = m_cm256DescriptorBlocks[recoveryIndex].Index; int blockIndex = m_cm256DescriptorBlocks[recoveryIndex].Index;
SDRDaemonProtectedBlock *recoveredBlock = RemoteProtectedBlock *recoveredBlock =
(SDRDaemonProtectedBlock *) m_cm256DescriptorBlocks[recoveryIndex].Block; (RemoteProtectedBlock *) m_cm256DescriptorBlocks[recoveryIndex].Block;
memcpy((void *) &(dataBlock->m_superBlocks[blockIndex].m_protectedBlock), recoveredBlock, sizeof(SDRDaemonProtectedBlock)); memcpy((void *) &(dataBlock->m_superBlocks[blockIndex].m_protectedBlock), recoveredBlock, sizeof(RemoteProtectedBlock));
if ((blockIndex == 0) && !dataBlock->m_rxControlBlock.m_metaRetrieved) { if ((blockIndex == 0) && !dataBlock->m_rxControlBlock.m_metaRetrieved) {
dataBlock->m_rxControlBlock.m_metaRetrieved = true; dataBlock->m_rxControlBlock.m_metaRetrieved = true;
} }
@ -318,7 +318,7 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
// Validate block zero and retrieve its data // Validate block zero and retrieve its data
if (dataBlock->m_rxControlBlock.m_metaRetrieved) if (dataBlock->m_rxControlBlock.m_metaRetrieved)
{ {
SDRDaemonMetaDataFEC *metaData = (SDRDaemonMetaDataFEC *) &(dataBlock->m_superBlocks[0].m_protectedBlock); RemoteMetaDataFEC *metaData = (RemoteMetaDataFEC *) &(dataBlock->m_superBlocks[0].m_protectedBlock);
boost::crc_32_type crc32; boost::crc_32_type crc32;
crc32.process_bytes(metaData, 20); crc32.process_bytes(metaData, 20);
@ -349,14 +349,14 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
void RemoteSource::handleData() void RemoteSource::handleData()
{ {
SDRDaemonDataBlock* dataBlock; RemoteDataBlock* dataBlock;
while (m_running && ((dataBlock = m_dataQueue.pop()) != 0)) { while (m_running && ((dataBlock = m_dataQueue.pop()) != 0)) {
handleDataBlock(dataBlock); handleDataBlock(dataBlock);
} }
} }
void RemoteSource::printMeta(const QString& header, SDRDaemonMetaDataFEC *metaData) void RemoteSource::printMeta(const QString& header, RemoteMetaDataFEC *metaData)
{ {
qDebug().noquote() << header << ": " qDebug().noquote() << header << ": "
<< "|" << metaData->m_centerFrequency << "|" << metaData->m_centerFrequency

Wyświetl plik

@ -17,6 +17,9 @@
#ifndef PLUGINS_CHANNELTX_REMOTESRC_REMOTESRC_H_ #ifndef PLUGINS_CHANNELTX_REMOTESRC_REMOTESRC_H_
#define PLUGINS_CHANNELTX_REMOTESRC_REMOTESRC_H_ #define PLUGINS_CHANNELTX_REMOTESRC_REMOTESRC_H_
#include <channel/remotedatablock.h>
#include <channel/remotedataqueue.h>
#include <channel/remotedatareadqueue.h>
#include <QObject> #include <QObject>
#include <QNetworkRequest> #include <QNetworkRequest>
@ -26,17 +29,13 @@
#include "channel/channelsourceapi.h" #include "channel/channelsourceapi.h"
#include "util/message.h" #include "util/message.h"
#include "channel/sdrdaemondataqueue.h"
#include "channel/sdrdaemondatablock.h"
#include "channel/sdrdaemondatareadqueue.h"
#include "../remotesource/remotesourcesettings.h" #include "../remotesource/remotesourcesettings.h"
class ThreadedBasebandSampleSource; class ThreadedBasebandSampleSource;
class UpChannelizer; class UpChannelizer;
class DeviceSinkAPI; class DeviceSinkAPI;
class RemoteSourceThread; class RemoteSourceThread;
class SDRDaemonDataBlock; class RemoteDataBlock;
class QNetworkAccessManager; class QNetworkAccessManager;
class QNetworkReply; class QNetworkReply;
@ -221,7 +220,7 @@ private:
DeviceSinkAPI* m_deviceAPI; DeviceSinkAPI* m_deviceAPI;
ThreadedBasebandSampleSource* m_threadedChannelizer; ThreadedBasebandSampleSource* m_threadedChannelizer;
UpChannelizer* m_channelizer; UpChannelizer* m_channelizer;
SDRDaemonDataQueue m_dataQueue; RemoteDataQueue m_dataQueue;
RemoteSourceThread *m_sourceThread; RemoteSourceThread *m_sourceThread;
CM256 m_cm256; CM256 m_cm256;
CM256 *m_cm256p; CM256 *m_cm256p;
@ -229,10 +228,10 @@ private:
RemoteSourceSettings m_settings; RemoteSourceSettings m_settings;
CM256::cm256_block m_cm256DescriptorBlocks[2*SDRDaemonNbOrginalBlocks]; //!< CM256 decoder descriptors (block addresses and block indexes) CM256::cm256_block m_cm256DescriptorBlocks[2*RemoteNbOrginalBlocks]; //!< CM256 decoder descriptors (block addresses and block indexes)
SDRDaemonMetaDataFEC m_currentMeta; RemoteMetaDataFEC m_currentMeta;
SDRDaemonDataReadQueue m_dataReadQueue; RemoteDataReadQueue m_dataReadQueue;
uint32_t m_nbCorrectableErrors; //!< count of correctable errors in number of blocks uint32_t m_nbCorrectableErrors; //!< count of correctable errors in number of blocks
uint32_t m_nbUncorrectableErrors; //!< count of uncorrectable errors in number of blocks uint32_t m_nbUncorrectableErrors; //!< count of uncorrectable errors in number of blocks
@ -241,8 +240,8 @@ private:
QNetworkRequest m_networkRequest; QNetworkRequest m_networkRequest;
void applySettings(const RemoteSourceSettings& settings, bool force = false); void applySettings(const RemoteSourceSettings& settings, bool force = false);
void handleDataBlock(SDRDaemonDataBlock *dataBlock); void handleDataBlock(RemoteDataBlock *dataBlock);
void printMeta(const QString& header, SDRDaemonMetaDataFEC *metaData); void printMeta(const QString& header, RemoteMetaDataFEC *metaData);
uint32_t calculateDataReadQueueSize(int sampleRate); uint32_t calculateDataReadQueueSize(int sampleRate);
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const RemoteSourceSettings& settings); void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const RemoteSourceSettings& settings);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);

Wyświetl plik

@ -16,26 +16,26 @@
#include "remotesourcethread.h" #include "remotesourcethread.h"
#include <channel/remotedatablock.h>
#include <channel/remotedataqueue.h>
#include <algorithm> #include <algorithm>
#include <QUdpSocket> #include <QUdpSocket>
#include "cm256.h" #include "cm256.h"
#include "channel/sdrdaemondataqueue.h"
#include "channel/sdrdaemondatablock.h"
MESSAGE_CLASS_DEFINITION(RemoteSourceThread::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(RemoteSourceThread::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(RemoteSourceThread::MsgDataBind, Message) MESSAGE_CLASS_DEFINITION(RemoteSourceThread::MsgDataBind, Message)
RemoteSourceThread::RemoteSourceThread(SDRDaemonDataQueue *dataQueue, QObject* parent) : RemoteSourceThread::RemoteSourceThread(RemoteDataQueue *dataQueue, QObject* parent) :
QThread(parent), QThread(parent),
m_running(false), m_running(false),
m_dataQueue(dataQueue), m_dataQueue(dataQueue),
m_address(QHostAddress::LocalHost), m_address(QHostAddress::LocalHost),
m_socket(0) m_socket(0)
{ {
std::fill(m_dataBlocks, m_dataBlocks+4, (SDRDaemonDataBlock *) 0); std::fill(m_dataBlocks, m_dataBlocks+4, (RemoteDataBlock *) 0);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
} }
@ -128,7 +128,7 @@ void RemoteSourceThread::handleInputMessages()
void RemoteSourceThread::readPendingDatagrams() void RemoteSourceThread::readPendingDatagrams()
{ {
SDRDaemonSuperBlock superBlock; RemoteSuperBlock superBlock;
qint64 size; qint64 size;
while (m_socket->hasPendingDatagrams()) while (m_socket->hasPendingDatagrams())
@ -136,15 +136,15 @@ void RemoteSourceThread::readPendingDatagrams()
QHostAddress sender; QHostAddress sender;
quint16 senderPort = 0; quint16 senderPort = 0;
//qint64 pendingDataSize = m_socket->pendingDatagramSize(); //qint64 pendingDataSize = m_socket->pendingDatagramSize();
size = m_socket->readDatagram((char *) &superBlock, (long long int) sizeof(SDRDaemonSuperBlock), &sender, &senderPort); size = m_socket->readDatagram((char *) &superBlock, (long long int) sizeof(RemoteSuperBlock), &sender, &senderPort);
if (size == sizeof(SDRDaemonSuperBlock)) if (size == sizeof(RemoteSuperBlock))
{ {
unsigned int dataBlockIndex = superBlock.m_header.m_frameIndex % m_nbDataBlocks; unsigned int dataBlockIndex = superBlock.m_header.m_frameIndex % m_nbDataBlocks;
// create the first block for this index // create the first block for this index
if (m_dataBlocks[dataBlockIndex] == 0) { if (m_dataBlocks[dataBlockIndex] == 0) {
m_dataBlocks[dataBlockIndex] = new SDRDaemonDataBlock(); m_dataBlocks[dataBlockIndex] = new RemoteDataBlock();
} }
if (m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_frameIndex < 0) if (m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_frameIndex < 0)
@ -159,9 +159,9 @@ void RemoteSourceThread::readPendingDatagrams()
if (superBlock.m_header.m_frameIndex != frameIndex) if (superBlock.m_header.m_frameIndex != frameIndex)
{ {
//qDebug("DaemonSourceThread::readPendingDatagrams: push frame %u", frameIndex); //qDebug("RemoteSourceThread::readPendingDatagrams: push frame %u", frameIndex);
m_dataQueue->push(m_dataBlocks[dataBlockIndex]); m_dataQueue->push(m_dataBlocks[dataBlockIndex]);
m_dataBlocks[dataBlockIndex] = new SDRDaemonDataBlock(); m_dataBlocks[dataBlockIndex] = new RemoteDataBlock();
m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_frameIndex = superBlock.m_header.m_frameIndex; m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_frameIndex = superBlock.m_header.m_frameIndex;
} }
} }
@ -172,7 +172,7 @@ void RemoteSourceThread::readPendingDatagrams()
m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_metaRetrieved = true; m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_metaRetrieved = true;
} }
if (superBlock.m_header.m_blockIndex < SDRDaemonNbOrginalBlocks) { if (superBlock.m_header.m_blockIndex < RemoteNbOrginalBlocks) {
m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_originalCount++; m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_originalCount++;
} else { } else {
m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_recoveryCount++; m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_recoveryCount++;

Wyświetl plik

@ -25,8 +25,8 @@
#include "util/message.h" #include "util/message.h"
#include "util/messagequeue.h" #include "util/messagequeue.h"
class SDRDaemonDataQueue; class RemoteDataQueue;
class SDRDaemonDataBlock; class RemoteDataBlock;
class QUdpSocket; class QUdpSocket;
class RemoteSourceThread : public QThread { class RemoteSourceThread : public QThread {
@ -74,7 +74,7 @@ public:
} }
}; };
RemoteSourceThread(SDRDaemonDataQueue *dataQueue, QObject* parent = 0); RemoteSourceThread(RemoteDataQueue *dataQueue, QObject* parent = 0);
~RemoteSourceThread(); ~RemoteSourceThread();
void startStop(bool start); void startStop(bool start);
@ -86,13 +86,13 @@ private:
volatile bool m_running; volatile bool m_running;
MessageQueue m_inputMessageQueue; MessageQueue m_inputMessageQueue;
SDRDaemonDataQueue *m_dataQueue; RemoteDataQueue *m_dataQueue;
QHostAddress m_address; QHostAddress m_address;
QUdpSocket *m_socket; QUdpSocket *m_socket;
static const uint32_t m_nbDataBlocks = 4; //!< number of data blocks in the ring buffer static const uint32_t m_nbDataBlocks = 4; //!< number of data blocks in the ring buffer
SDRDaemonDataBlock *m_dataBlocks[m_nbDataBlocks]; //!< ring buffer of data blocks indexed by frame affinity RemoteDataBlock *m_dataBlocks[m_nbDataBlocks]; //!< ring buffer of data blocks indexed by frame affinity
void startWork(); void startWork();
void stopWork(); void stopWork();

Wyświetl plik

@ -25,7 +25,7 @@ endif(LIBUSB_FOUND AND LIBIIO_FOUND)
find_package(CM256cc) find_package(CM256cc)
if(CM256CC_FOUND) if(CM256CC_FOUND)
add_subdirectory(sdrdaemonsink) add_subdirectory(remoteoutput)
endif(CM256CC_FOUND) endif(CM256CC_FOUND)
find_package(SoapySDR) find_package(SoapySDR)
@ -44,7 +44,7 @@ if (BUILD_DEBIAN)
add_subdirectory(hackrfoutput) add_subdirectory(hackrfoutput)
add_subdirectory(limesdroutput) add_subdirectory(limesdroutput)
add_subdirectory(plutosdroutput) add_subdirectory(plutosdroutput)
add_subdirectory(sdrdaemonsink) add_subdirectory(remoteoutput)
add_subdirectory(soapysdroutput) add_subdirectory(soapysdroutput)
endif (BUILD_DEBIAN) endif (BUILD_DEBIAN)

Wyświetl plik

@ -54,7 +54,7 @@ This is the Tx filter bandwidth in kHz. Minimum and maximum values are adjusted
This button opens a dialog to set the transverter mode frequency translation options: This button opens a dialog to set the transverter mode frequency translation options:
![SDR Daemon source input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png) ![BladeRF2 source input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png)
Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit. Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit.

Wyświetl plik

@ -85,7 +85,7 @@ This is the frequency shift applied when the NCO is engaged thus the actual LO f
This button opens a dialog to set the transverter mode frequency translation options: This button opens a dialog to set the transverter mode frequency translation options:
![SDR Daemon source input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png) ![LimeSDR source input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png)
Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit. Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit.

Wyświetl plik

@ -63,7 +63,7 @@ Use this slider to adjust LO correction in ppm. It can be varied from -20.0 to 2
This button opens a dialog to set the transverter mode frequency translation options: This button opens a dialog to set the transverter mode frequency translation options:
![SDR Daemon source input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png) ![PlutoSDR source input stream transverter dialog](../../../doc/img/RTLSDR_plugin_xvrt.png)
Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit. Note that if you mouse over the button a tooltip appears that displays the translating frequency and if translation is enabled or disabled. When the frequency translation is enabled the button is lit.

Wyświetl plik

@ -0,0 +1,87 @@
project(remoteoutput)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if (HAS_SSSE3)
message(STATUS "RemoteFEC: use SSSE3 SIMD" )
elseif (HAS_NEON)
message(STATUS "RemoteFEC: use Neon SIMD" )
else()
message(STATUS "RemoteFEC: Unsupported architecture")
return()
endif()
set(remoteoutput_SOURCES
remoteoutputgui.cpp
remoteoutput.cpp
remoteoutputplugin.cpp
remoteoutputsettings.cpp
remoteoutputthread.cpp
udpsinkfec.cpp
udpsinkfecworker.cpp
)
set(remoteoutput_HEADERS
remoteoutputgui.h
remoteoutput.h
remoteoutputplugin.h
remoteoutputsettings.h
remoteoutputthreads.h
udpsinkfec.h
udpsinkfecworker.h
)
set(remoteoutput_FORMS
remoteoutputgui.ui
)
if (BUILD_DEBIAN)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${LIBCM256CCSRC}
)
else (BUILD_DEBIAN)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${CMAKE_SOURCE_DIR}/devices
${CM256CC_INCLUDE_DIR}
)
endif (BUILD_DEBIAN)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
qt5_wrap_ui(remoteoutput_FORMS_HEADERS ${remoteoutput_FORMS})
add_library(outputremote SHARED
${remoteoutput_SOURCES}
${remoteoutput_HEADERS_MOC}
${remoteoutput_FORMS_HEADERS}
)
if (BUILD_DEBIAN)
target_link_libraries(outputremote
${QT_LIBRARIES}
sdrbase
sdrgui
swagger
cm256cc
)
else (BUILD_DEBIAN)
target_link_libraries(outputremote
${QT_LIBRARIES}
sdrbase
sdrgui
swagger
${CM256CC_LIBRARIES}
)
endif (BUILD_DEBIAN)
target_link_libraries(outputremote Qt5::Core Qt5::Widgets)
install(TARGETS outputremote DESTINATION lib/plugins/samplesink)

Wyświetl plik

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// SDRdaemon - send I/Q samples read from a SDR device over the network via UDP. // // Remote - send I/Q samples read from a SDR device over the network via UDP. //
// // // //
// Copyright (C) 2015 Edouard Griffiths, F4EXB // // Copyright (C) 2015 Edouard Griffiths, F4EXB //
// // // //
@ -19,6 +19,7 @@
// Original code is posted at: https://cppcodetips.wordpress.com/2014/01/29/udp-socket-class-in-c/ // Original code is posted at: https://cppcodetips.wordpress.com/2014/01/29/udp-socket-class-in-c/
#include "UDPSocket.h" #include "UDPSocket.h"
#include <errno.h> #include <errno.h>
#include <cstring> #include <cstring>
#include <fcntl.h> #include <fcntl.h>

Wyświetl plik

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// SDRdaemon - send I/Q samples read from a SDR device over the network via UDP. // // Remote - send I/Q samples read from a SDR device over the network via UDP. //
// // // //
// Copyright (C) 2015 Edouard Griffiths, F4EXB // // Copyright (C) 2015 Edouard Griffiths, F4EXB //
// // // //

Wyświetl plik

@ -1,14 +1,14 @@
<h1>SDRdaemon sink plugin</h1> <h1>Remote output plugin</h1>
<h2>Introduction</h2> <h2>Introduction</h2>
This output sample sink plugin sends its samples over tbe network to a SDRangel instance's Daemon source channel using UDP connection. This output sample sink plugin sends its samples over the network to a SDRangel instance's Remote source channel using UDP connection.
Forward Error Correction with a Cauchy MDS block erasure codec is used to prevent block loss. This can make the UDP transmission more robust particularly over WiFi links. Forward Error Correction with a Cauchy MDS block erasure codec is used to prevent block loss. This can make the UDP transmission more robust particularly over WiFi links.
The distant SDRangel instance to which the data stream is sent is controlled via its REST API using a separate control software for example [SDRangelcli](https://github.com/f4exb/sdrangelcli) The distant SDRangel instance to which the data stream is sent is controlled via its REST API using a separate control software for example [SDRangelcli](https://github.com/f4exb/sdrangelcli)
The sample size used in the I/Q stream is the Rx sample size of the local instance. Possible conversion takes place in the distant Daemon source channel plugin to match the Rx sample size of the distant instance. Best performace is obtained when both instances use the same sample size. The sample size used in the I/Q stream is the Rx sample size of the local instance. Possible conversion takes place in the distant Remote source channel plugin to match the Rx sample size of the distant instance. Best performace is obtained when both instances use the same sample size.
It is present only in Linux binary releases. It is present only in Linux binary releases.
@ -18,7 +18,7 @@ The plugin will be built only if the [CM256cc library](https://github.com/f4exb/
<h2>Interface</h2> <h2>Interface</h2>
![SDR Daemon sink output plugin GUI](../../../doc/img/SDRdaemonSink_plugin.png) ![SDR Remote output plugin GUI](../../../doc/img/RemoteOutput_plugin.png)
<h3>1: Start/Stop</h3> <h3>1: Start/Stop</h3>
@ -41,7 +41,7 @@ This is the remote instance baseband sample rate. It can be a power of two multi
<h3>5: Stream controls and API destination</h3> <h3>5: Stream controls and API destination</h3>
![SDR Daemon sink output sample rate GUI](../../../doc/img/SDRdaemonSink_plugin_05.png) ![SDR Remote output sample rate GUI](../../../doc/img/RemoteOutput_plugin_05.png)
<h4>5.1: Network stream sample rate</h4> <h4>5.1: Network stream sample rate</h4>
@ -66,11 +66,11 @@ This is the device set index in the remote instance to which the stream is conne
<h4>5.4: remote instance channel index</h4> <h4>5.4: remote instance channel index</h4>
This is the channel index of the Daemon source in the remote instance to which the stream is connected to. Use this value to properly address the API to get status. This is the channel index of the Remote source in the remote instance to which the stream is connected to. Use this value to properly address the API to get status.
<h3>6: Forward Error Correction setting and status</h3> <h3>6: Forward Error Correction setting and status</h3>
![SDR Daemon sink output FEC GUI](../../../doc/img/SDRdaemonSink_plugin_06.png) ![SDR Remote output FEC GUI](../../../doc/img/RemoteOutput_plugin_06.png)
<h4>6.1: Desired number of FEC blocks per frame</h4> <h4>6.1: Desired number of FEC blocks per frame</h4>
@ -115,7 +115,7 @@ This is the detail of the ratio shown in the gauge. Each frame block is a block
<h3>9: Distant server API address and port</h3> <h3>9: Distant server API address and port</h3>
![SDR Daemon source input stream GUI](../../../doc/img/SDRdaemonSource_plugin_05.png) ![SDR Remote input stream GUI](../../../doc/img/SDRdaemonSource_plugin_05.png)
<h4>9.1: API connection indicator</h4> <h4>9.1: API connection indicator</h4>
@ -135,7 +135,7 @@ When the return key is hit within the address (9.2) or port (9.3) the changes ar
<h3>10: Local data address and port</h3> <h3>10: Local data address and port</h3>
![SDR Daemon source input stream GUI](../../../doc/img/SDRdaemonSource_plugin_06.png) ![SDR Remote input stream GUI](../../../doc/img/SDRdaemonSource_plugin_06.png)
<h4>10.1: Data IP address</h4> <h4>10.1: Data IP address</h4>

Wyświetl plik

@ -34,22 +34,22 @@
#include "device/devicesinkapi.h" #include "device/devicesinkapi.h"
#include "sdrdaemonsinkoutput.h" #include "remoteoutput.h"
#include "sdrdaemonsinkthread.h" #include "remoteoutputthread.h"
MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink, Message) MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutput, Message)
MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSinkWork, Message) MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputWork, Message)
MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgStartStop, Message) MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(SDRdaemonSinkOutput::MsgConfigureSDRdaemonSinkChunkCorrection, Message) MESSAGE_CLASS_DEFINITION(RemoteOutput::MsgConfigureRemoteOutputChunkCorrection, Message)
const uint32_t SDRdaemonSinkOutput::NbSamplesForRateCorrection = 5000000; const uint32_t RemoteOutput::NbSamplesForRateCorrection = 5000000;
SDRdaemonSinkOutput::SDRdaemonSinkOutput(DeviceSinkAPI *deviceAPI) : RemoteOutput::RemoteOutput(DeviceSinkAPI *deviceAPI) :
m_deviceAPI(deviceAPI), m_deviceAPI(deviceAPI),
m_settings(), m_settings(),
m_centerFrequency(0), m_centerFrequency(0),
m_sdrDaemonSinkThread(0), m_remoteOutputThread(0),
m_deviceDescription("SDRdaemonSink"), m_deviceDescription("RemoteOutput"),
m_startingTimeStamp(0), m_startingTimeStamp(0),
m_masterTimer(deviceAPI->getMasterTimer()), m_masterTimer(deviceAPI->getMasterTimer()),
m_tickCount(0), m_tickCount(0),
@ -68,29 +68,29 @@ SDRdaemonSinkOutput::SDRdaemonSinkOutput(DeviceSinkAPI *deviceAPI) :
connect(&m_masterTimer, SIGNAL(timeout()), this, SLOT(tick())); connect(&m_masterTimer, SIGNAL(timeout()), this, SLOT(tick()));
} }
SDRdaemonSinkOutput::~SDRdaemonSinkOutput() RemoteOutput::~RemoteOutput()
{ {
disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
stop(); stop();
delete m_networkManager; delete m_networkManager;
} }
void SDRdaemonSinkOutput::destroy() void RemoteOutput::destroy()
{ {
delete this; delete this;
} }
bool SDRdaemonSinkOutput::start() bool RemoteOutput::start()
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
qDebug() << "SDRdaemonSinkOutput::start"; qDebug() << "RemoteOutput::start";
m_sdrDaemonSinkThread = new SDRdaemonSinkThread(&m_sampleSourceFifo); m_remoteOutputThread = new RemoteOutputThread(&m_sampleSourceFifo);
m_sdrDaemonSinkThread->setDataAddress(m_settings.m_dataAddress, m_settings.m_dataPort); m_remoteOutputThread->setDataAddress(m_settings.m_dataAddress, m_settings.m_dataPort);
m_sdrDaemonSinkThread->setSamplerate(m_settings.m_sampleRate); m_remoteOutputThread->setSamplerate(m_settings.m_sampleRate);
m_sdrDaemonSinkThread->setNbBlocksFEC(m_settings.m_nbFECBlocks); m_remoteOutputThread->setNbBlocksFEC(m_settings.m_nbFECBlocks);
m_sdrDaemonSinkThread->connectTimer(m_masterTimer); m_remoteOutputThread->connectTimer(m_masterTimer);
m_sdrDaemonSinkThread->startWork(); m_remoteOutputThread->startWork();
// restart auto rate correction // restart auto rate correction
m_lastRemoteTimestampRateCorrection = 0; m_lastRemoteTimestampRateCorrection = 0;
@ -98,39 +98,39 @@ bool SDRdaemonSinkOutput::start()
m_lastQueueLength = -2; // set first value out of bounds m_lastQueueLength = -2; // set first value out of bounds
m_chunkSizeCorrection = 0; m_chunkSizeCorrection = 0;
m_sdrDaemonSinkThread->setTxDelay(m_settings.m_txDelay); m_remoteOutputThread->setTxDelay(m_settings.m_txDelay);
mutexLocker.unlock(); mutexLocker.unlock();
//applySettings(m_generalSettings, m_settings, true); //applySettings(m_generalSettings, m_settings, true);
qDebug("SDRdaemonSinkOutput::start: started"); qDebug("RemoteOutput::start: started");
return true; return true;
} }
void SDRdaemonSinkOutput::init() void RemoteOutput::init()
{ {
applySettings(m_settings, true); applySettings(m_settings, true);
} }
void SDRdaemonSinkOutput::stop() void RemoteOutput::stop()
{ {
qDebug() << "SDRdaemonSinkOutput::stop"; qDebug() << "RemoteOutput::stop";
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
if(m_sdrDaemonSinkThread != 0) if(m_remoteOutputThread != 0)
{ {
m_sdrDaemonSinkThread->stopWork(); m_remoteOutputThread->stopWork();
delete m_sdrDaemonSinkThread; delete m_remoteOutputThread;
m_sdrDaemonSinkThread = 0; m_remoteOutputThread = 0;
} }
} }
QByteArray SDRdaemonSinkOutput::serialize() const QByteArray RemoteOutput::serialize() const
{ {
return m_settings.serialize(); return m_settings.serialize();
} }
bool SDRdaemonSinkOutput::deserialize(const QByteArray& data) bool RemoteOutput::deserialize(const QByteArray& data)
{ {
bool success = true; bool success = true;
@ -140,62 +140,62 @@ bool SDRdaemonSinkOutput::deserialize(const QByteArray& data)
success = false; success = false;
} }
MsgConfigureSDRdaemonSink* message = MsgConfigureSDRdaemonSink::create(m_settings, true); MsgConfigureRemoteOutput* message = MsgConfigureRemoteOutput::create(m_settings, true);
m_inputMessageQueue.push(message); m_inputMessageQueue.push(message);
if (m_guiMessageQueue) if (m_guiMessageQueue)
{ {
MsgConfigureSDRdaemonSink* messageToGUI = MsgConfigureSDRdaemonSink::create(m_settings, true); MsgConfigureRemoteOutput* messageToGUI = MsgConfigureRemoteOutput::create(m_settings, true);
m_guiMessageQueue->push(messageToGUI); m_guiMessageQueue->push(messageToGUI);
} }
return success; return success;
} }
const QString& SDRdaemonSinkOutput::getDeviceDescription() const const QString& RemoteOutput::getDeviceDescription() const
{ {
return m_deviceDescription; return m_deviceDescription;
} }
int SDRdaemonSinkOutput::getSampleRate() const int RemoteOutput::getSampleRate() const
{ {
return m_settings.m_sampleRate; return m_settings.m_sampleRate;
} }
quint64 SDRdaemonSinkOutput::getCenterFrequency() const quint64 RemoteOutput::getCenterFrequency() const
{ {
return m_centerFrequency; return m_centerFrequency;
} }
std::time_t SDRdaemonSinkOutput::getStartingTimeStamp() const std::time_t RemoteOutput::getStartingTimeStamp() const
{ {
return m_startingTimeStamp; return m_startingTimeStamp;
} }
bool SDRdaemonSinkOutput::handleMessage(const Message& message) bool RemoteOutput::handleMessage(const Message& message)
{ {
if (MsgConfigureSDRdaemonSink::match(message)) if (MsgConfigureRemoteOutput::match(message))
{ {
qDebug() << "SDRdaemonSinkOutput::handleMessage:" << message.getIdentifier(); qDebug() << "RemoteOutput::handleMessage:" << message.getIdentifier();
MsgConfigureSDRdaemonSink& conf = (MsgConfigureSDRdaemonSink&) message; MsgConfigureRemoteOutput& conf = (MsgConfigureRemoteOutput&) message;
applySettings(conf.getSettings(), conf.getForce()); applySettings(conf.getSettings(), conf.getForce());
return true; return true;
} }
else if (MsgConfigureSDRdaemonSinkWork::match(message)) else if (MsgConfigureRemoteOutputWork::match(message))
{ {
MsgConfigureSDRdaemonSinkWork& conf = (MsgConfigureSDRdaemonSinkWork&) message; MsgConfigureRemoteOutputWork& conf = (MsgConfigureRemoteOutputWork&) message;
bool working = conf.isWorking(); bool working = conf.isWorking();
if (m_sdrDaemonSinkThread != 0) if (m_remoteOutputThread != 0)
{ {
if (working) if (working)
{ {
m_sdrDaemonSinkThread->startWork(); m_remoteOutputThread->startWork();
} }
else else
{ {
m_sdrDaemonSinkThread->stopWork(); m_remoteOutputThread->stopWork();
} }
} }
@ -204,7 +204,7 @@ bool SDRdaemonSinkOutput::handleMessage(const Message& message)
else if (MsgStartStop::match(message)) else if (MsgStartStop::match(message))
{ {
MsgStartStop& cmd = (MsgStartStop&) message; MsgStartStop& cmd = (MsgStartStop&) message;
qDebug() << "SDRdaemonSinkOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); qDebug() << "RemoteOutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop()) if (cmd.getStartStop())
{ {
@ -224,13 +224,13 @@ bool SDRdaemonSinkOutput::handleMessage(const Message& message)
return true; return true;
} }
else if (MsgConfigureSDRdaemonSinkChunkCorrection::match(message)) else if (MsgConfigureRemoteOutputChunkCorrection::match(message))
{ {
MsgConfigureSDRdaemonSinkChunkCorrection& conf = (MsgConfigureSDRdaemonSinkChunkCorrection&) message; MsgConfigureRemoteOutputChunkCorrection& conf = (MsgConfigureRemoteOutputChunkCorrection&) message;
if (m_sdrDaemonSinkThread != 0) if (m_remoteOutputThread != 0)
{ {
m_sdrDaemonSinkThread->setChunkCorrection(conf.getChunkCorrection()); m_remoteOutputThread->setChunkCorrection(conf.getChunkCorrection());
} }
return true; return true;
@ -241,7 +241,7 @@ bool SDRdaemonSinkOutput::handleMessage(const Message& message)
} }
} }
void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, bool force) void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool force)
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
bool forwardChange = false; bool forwardChange = false;
@ -263,8 +263,8 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b
if (force || (m_settings.m_dataAddress != settings.m_dataAddress) || (m_settings.m_dataPort != settings.m_dataPort)) if (force || (m_settings.m_dataAddress != settings.m_dataAddress) || (m_settings.m_dataPort != settings.m_dataPort))
{ {
if (m_sdrDaemonSinkThread != 0) { if (m_remoteOutputThread != 0) {
m_sdrDaemonSinkThread->setDataAddress(settings.m_dataAddress, settings.m_dataPort); m_remoteOutputThread->setDataAddress(settings.m_dataAddress, settings.m_dataPort);
} }
} }
@ -272,8 +272,8 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b
{ {
reverseAPIKeys.append("sampleRate"); reverseAPIKeys.append("sampleRate");
if (m_sdrDaemonSinkThread != 0) { if (m_remoteOutputThread != 0) {
m_sdrDaemonSinkThread->setSamplerate(settings.m_sampleRate); m_remoteOutputThread->setSamplerate(settings.m_sampleRate);
} }
m_tickMultiplier = (21*NbSamplesForRateCorrection) / (2*settings.m_sampleRate); // two times per sample filling period plus small extension m_tickMultiplier = (21*NbSamplesForRateCorrection) / (2*settings.m_sampleRate); // two times per sample filling period plus small extension
@ -287,8 +287,8 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b
{ {
reverseAPIKeys.append("nbFECBlocks"); reverseAPIKeys.append("nbFECBlocks");
if (m_sdrDaemonSinkThread != 0) { if (m_remoteOutputThread != 0) {
m_sdrDaemonSinkThread->setNbBlocksFEC(settings.m_nbFECBlocks); m_remoteOutputThread->setNbBlocksFEC(settings.m_nbFECBlocks);
} }
changeTxDelay = true; changeTxDelay = true;
@ -302,14 +302,14 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b
if (changeTxDelay) if (changeTxDelay)
{ {
if (m_sdrDaemonSinkThread != 0) { if (m_remoteOutputThread != 0) {
m_sdrDaemonSinkThread->setTxDelay(settings.m_txDelay); m_remoteOutputThread->setTxDelay(settings.m_txDelay);
} }
} }
mutexLocker.unlock(); mutexLocker.unlock();
qDebug() << "SDRdaemonSinkOutput::applySettings:" qDebug() << "RemoteOutput::applySettings:"
<< " m_sampleRate: " << settings.m_sampleRate << " m_sampleRate: " << settings.m_sampleRate
<< " m_txDelay: " << settings.m_txDelay << " m_txDelay: " << settings.m_txDelay
<< " m_nbFECBlocks: " << settings.m_nbFECBlocks << " m_nbFECBlocks: " << settings.m_nbFECBlocks
@ -336,7 +336,7 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b
m_settings = settings; m_settings = settings;
} }
int SDRdaemonSinkOutput::webapiRunGet( int RemoteOutput::webapiRunGet(
SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGDeviceState& response,
QString& errorMessage) QString& errorMessage)
{ {
@ -345,7 +345,7 @@ int SDRdaemonSinkOutput::webapiRunGet(
return 200; return 200;
} }
int SDRdaemonSinkOutput::webapiRun( int RemoteOutput::webapiRun(
bool run, bool run,
SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGDeviceState& response,
QString& errorMessage) QString& errorMessage)
@ -364,7 +364,7 @@ int SDRdaemonSinkOutput::webapiRun(
return 200; return 200;
} }
int SDRdaemonSinkOutput::webapiSettingsGet( int RemoteOutput::webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response, SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage) QString& errorMessage)
{ {
@ -375,14 +375,14 @@ int SDRdaemonSinkOutput::webapiSettingsGet(
return 200; return 200;
} }
int SDRdaemonSinkOutput::webapiSettingsPutPatch( int RemoteOutput::webapiSettingsPutPatch(
bool force, bool force,
const QStringList& deviceSettingsKeys, const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage) QString& errorMessage)
{ {
(void) errorMessage; (void) errorMessage;
SDRdaemonSinkSettings settings = m_settings; RemoteOutputSettings settings = m_settings;
if (deviceSettingsKeys.contains("sampleRate")) { if (deviceSettingsKeys.contains("sampleRate")) {
settings.m_sampleRate = response.getSdrDaemonSinkSettings()->getSampleRate(); settings.m_sampleRate = response.getSdrDaemonSinkSettings()->getSampleRate();
@ -424,12 +424,12 @@ int SDRdaemonSinkOutput::webapiSettingsPutPatch(
settings.m_reverseAPIDeviceIndex = response.getSdrDaemonSinkSettings()->getReverseApiDeviceIndex(); settings.m_reverseAPIDeviceIndex = response.getSdrDaemonSinkSettings()->getReverseApiDeviceIndex();
} }
MsgConfigureSDRdaemonSink *msg = MsgConfigureSDRdaemonSink::create(settings, force); MsgConfigureRemoteOutput *msg = MsgConfigureRemoteOutput::create(settings, force);
m_inputMessageQueue.push(msg); m_inputMessageQueue.push(msg);
if (m_guiMessageQueue) // forward to GUI if any if (m_guiMessageQueue) // forward to GUI if any
{ {
MsgConfigureSDRdaemonSink *msgToGUI = MsgConfigureSDRdaemonSink::create(settings, force); MsgConfigureRemoteOutput *msgToGUI = MsgConfigureRemoteOutput::create(settings, force);
m_guiMessageQueue->push(msgToGUI); m_guiMessageQueue->push(msgToGUI);
} }
@ -437,7 +437,7 @@ int SDRdaemonSinkOutput::webapiSettingsPutPatch(
return 200; return 200;
} }
int SDRdaemonSinkOutput::webapiReportGet( int RemoteOutput::webapiReportGet(
SWGSDRangel::SWGDeviceReport& response, SWGSDRangel::SWGDeviceReport& response,
QString& errorMessage) QString& errorMessage)
{ {
@ -448,7 +448,7 @@ int SDRdaemonSinkOutput::webapiReportGet(
return 200; return 200;
} }
void SDRdaemonSinkOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SDRdaemonSinkSettings& settings) void RemoteOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const RemoteOutputSettings& settings)
{ {
response.getSdrDaemonSinkSettings()->setCenterFrequency(m_centerFrequency); response.getSdrDaemonSinkSettings()->setCenterFrequency(m_centerFrequency);
response.getSdrDaemonSinkSettings()->setSampleRate(settings.m_sampleRate); response.getSdrDaemonSinkSettings()->setSampleRate(settings.m_sampleRate);
@ -472,14 +472,14 @@ void SDRdaemonSinkOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSetti
response.getSdrDaemonSinkSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); response.getSdrDaemonSinkSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
} }
void SDRdaemonSinkOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) void RemoteOutput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response)
{ {
uint64_t ts_usecs; uint64_t ts_usecs;
response.getSdrDaemonSinkReport()->setBufferRwBalance(m_sampleSourceFifo.getRWBalance()); response.getSdrDaemonSinkReport()->setBufferRwBalance(m_sampleSourceFifo.getRWBalance());
response.getSdrDaemonSinkReport()->setSampleCount(m_sdrDaemonSinkThread ? (int) m_sdrDaemonSinkThread->getSamplesCount(ts_usecs) : 0); response.getSdrDaemonSinkReport()->setSampleCount(m_remoteOutputThread ? (int) m_remoteOutputThread->getSamplesCount(ts_usecs) : 0);
} }
void SDRdaemonSinkOutput::tick() void RemoteOutput::tick()
{ {
if (++m_tickCount == m_tickMultiplier) if (++m_tickCount == m_tickMultiplier)
{ {
@ -498,11 +498,11 @@ void SDRdaemonSinkOutput::tick()
} }
} }
void SDRdaemonSinkOutput::networkManagerFinished(QNetworkReply *reply) void RemoteOutput::networkManagerFinished(QNetworkReply *reply)
{ {
if (reply->error()) if (reply->error())
{ {
qInfo("SDRdaemonSinkOutput::networkManagerFinished: error: %s", qPrintable(reply->errorString())); qInfo("RemoteOutput::networkManagerFinished: error: %s", qPrintable(reply->errorString()));
return; return;
} }
@ -521,24 +521,24 @@ void SDRdaemonSinkOutput::networkManagerFinished(QNetworkReply *reply)
else else
{ {
QString errorMsg = QString("Reply JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset); QString errorMsg = QString("Reply JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset);
qInfo().noquote() << "SDRdaemonSinkOutput::networkManagerFinished" << errorMsg; qInfo().noquote() << "RemoteOutput::networkManagerFinished" << errorMsg;
} }
} }
catch (const std::exception& ex) catch (const std::exception& ex)
{ {
QString errorMsg = QString("Error parsing request: ") + ex.what(); QString errorMsg = QString("Error parsing request: ") + ex.what();
qInfo().noquote() << "SDRdaemonSinkOutput::networkManagerFinished" << errorMsg; qInfo().noquote() << "RemoteOutput::networkManagerFinished" << errorMsg;
} }
} }
void SDRdaemonSinkOutput::analyzeApiReply(const QJsonObject& jsonObject, const QString& answer) void RemoteOutput::analyzeApiReply(const QJsonObject& jsonObject, const QString& answer)
{ {
if (jsonObject.contains("DaemonSourceReport")) if (jsonObject.contains("DaemonSourceReport"))
{ {
QJsonObject report = jsonObject["DaemonSourceReport"].toObject(); QJsonObject report = jsonObject["DaemonSourceReport"].toObject();
m_centerFrequency = report["deviceCenterFreq"].toInt() * 1000; m_centerFrequency = report["deviceCenterFreq"].toInt() * 1000;
if (!m_sdrDaemonSinkThread) { if (!m_remoteOutputThread) {
return; return;
} }
@ -559,7 +559,7 @@ void SDRdaemonSinkOutput::analyzeApiReply(const QJsonObject& jsonObject, const Q
uint32_t sampleCountDelta, sampleCount; uint32_t sampleCountDelta, sampleCount;
uint64_t timestampUs; uint64_t timestampUs;
sampleCount = m_sdrDaemonSinkThread->getSamplesCount(timestampUs); sampleCount = m_remoteOutputThread->getSamplesCount(timestampUs);
if (sampleCount < m_lastSampleCount) { if (sampleCount < m_lastSampleCount) {
sampleCountDelta = (0xFFFFFFFFU - m_lastSampleCount) + sampleCount + 1; sampleCountDelta = (0xFFFFFFFFU - m_lastSampleCount) + sampleCount + 1;
@ -580,7 +580,7 @@ void SDRdaemonSinkOutput::analyzeApiReply(const QJsonObject& jsonObject, const Q
m_nbRemoteSamplesSinceRateCorrection += remoteSampleCountDelta; m_nbRemoteSamplesSinceRateCorrection += remoteSampleCountDelta;
m_nbSamplesSinceRateCorrection += sampleCountDelta; m_nbSamplesSinceRateCorrection += sampleCountDelta;
qDebug("SDRdaemonSinkOutput::analyzeApiReply: queueLengthPercent: %d m_nbSamplesSinceRateCorrection: %u", qDebug("RemoteOutput::analyzeApiReply: queueLengthPercent: %d m_nbSamplesSinceRateCorrection: %u",
queueLengthPercent, queueLengthPercent,
m_nbRemoteSamplesSinceRateCorrection); m_nbRemoteSamplesSinceRateCorrection);
@ -603,23 +603,23 @@ void SDRdaemonSinkOutput::analyzeApiReply(const QJsonObject& jsonObject, const Q
} }
else if (jsonObject.contains("sdrDaemonSinkSettings")) else if (jsonObject.contains("sdrDaemonSinkSettings"))
{ {
qDebug("SDRdaemonSinkOutput::analyzeApiReply: reply:\n%s", answer.toStdString().c_str()); qDebug("RemoteOutput::analyzeApiReply: reply:\n%s", answer.toStdString().c_str());
} }
} }
void SDRdaemonSinkOutput::sampleRateCorrection(double remoteTimeDeltaUs, double timeDeltaUs, uint32_t remoteSampleCount, uint32_t sampleCount) void RemoteOutput::sampleRateCorrection(double remoteTimeDeltaUs, double timeDeltaUs, uint32_t remoteSampleCount, uint32_t sampleCount)
{ {
double deltaSR = (remoteSampleCount/remoteTimeDeltaUs) - (sampleCount/timeDeltaUs); double deltaSR = (remoteSampleCount/remoteTimeDeltaUs) - (sampleCount/timeDeltaUs);
double chunkCorr = 50000 * deltaSR; // for 50ms chunk intervals (50000us) double chunkCorr = 50000 * deltaSR; // for 50ms chunk intervals (50000us)
m_chunkSizeCorrection += roundf(chunkCorr); m_chunkSizeCorrection += roundf(chunkCorr);
qDebug("SDRdaemonSinkOutput::sampleRateCorrection: %d (%f) samples", m_chunkSizeCorrection, chunkCorr); qDebug("RemoteOutput::sampleRateCorrection: %d (%f) samples", m_chunkSizeCorrection, chunkCorr);
MsgConfigureSDRdaemonSinkChunkCorrection* message = MsgConfigureSDRdaemonSinkChunkCorrection::create(m_chunkSizeCorrection); MsgConfigureRemoteOutputChunkCorrection* message = MsgConfigureRemoteOutputChunkCorrection::create(m_chunkSizeCorrection);
getInputMessageQueue()->push(message); getInputMessageQueue()->push(message);
} }
void SDRdaemonSinkOutput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const SDRdaemonSinkSettings& settings, bool force) void RemoteOutput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const RemoteOutputSettings& settings, bool force)
{ {
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings(); SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setTx(1); swgDeviceSettings->setTx(1);
@ -675,7 +675,7 @@ void SDRdaemonSinkOutput::webapiReverseSendSettings(QList<QString>& deviceSettin
delete swgDeviceSettings; delete swgDeviceSettings;
} }
void SDRdaemonSinkOutput::webapiReverseSendStartStop(bool start) void RemoteOutput::webapiReverseSendStartStop(bool start)
{ {
QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run") QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
.arg(m_settings.m_reverseAPIAddress) .arg(m_settings.m_reverseAPIAddress)

Wyświetl plik

@ -14,8 +14,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_SDRDAEMONSINKOUTPUT_H #ifndef INCLUDE_REMOTEOUTPUT_H
#define INCLUDE_SDRDAEMONSINKOUTPUT_H #define INCLUDE_REMOTEOUTPUT_H
#include <ctime> #include <ctime>
#include <iostream> #include <iostream>
@ -28,55 +28,55 @@
#include "dsp/devicesamplesink.h" #include "dsp/devicesamplesink.h"
#include "sdrdaemonsinksettings.h" #include "remoteoutputsettings.h"
class SDRdaemonSinkThread; class RemoteOutputThread;
class DeviceSinkAPI; class DeviceSinkAPI;
class QNetworkAccessManager; class QNetworkAccessManager;
class QNetworkReply; class QNetworkReply;
class QJsonObject; class QJsonObject;
class SDRdaemonSinkOutput : public DeviceSampleSink { class RemoteOutput : public DeviceSampleSink {
Q_OBJECT Q_OBJECT
public: public:
class MsgConfigureSDRdaemonSink : public Message { class MsgConfigureRemoteOutput : public Message {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
public: public:
const SDRdaemonSinkSettings& getSettings() const { return m_settings; } const RemoteOutputSettings& getSettings() const { return m_settings; }
bool getForce() const { return m_force; } bool getForce() const { return m_force; }
static MsgConfigureSDRdaemonSink* create(const SDRdaemonSinkSettings& settings, bool force = false) static MsgConfigureRemoteOutput* create(const RemoteOutputSettings& settings, bool force = false)
{ {
return new MsgConfigureSDRdaemonSink(settings, force); return new MsgConfigureRemoteOutput(settings, force);
} }
private: private:
SDRdaemonSinkSettings m_settings; RemoteOutputSettings m_settings;
bool m_force; bool m_force;
MsgConfigureSDRdaemonSink(const SDRdaemonSinkSettings& settings, bool force) : MsgConfigureRemoteOutput(const RemoteOutputSettings& settings, bool force) :
Message(), Message(),
m_settings(settings), m_settings(settings),
m_force(force) m_force(force)
{ } { }
}; };
class MsgConfigureSDRdaemonSinkWork : public Message { class MsgConfigureRemoteOutputWork : public Message {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
public: public:
bool isWorking() const { return m_working; } bool isWorking() const { return m_working; }
static MsgConfigureSDRdaemonSinkWork* create(bool working) static MsgConfigureRemoteOutputWork* create(bool working)
{ {
return new MsgConfigureSDRdaemonSinkWork(working); return new MsgConfigureRemoteOutputWork(working);
} }
private: private:
bool m_working; bool m_working;
MsgConfigureSDRdaemonSinkWork(bool working) : MsgConfigureRemoteOutputWork(bool working) :
Message(), Message(),
m_working(working) m_working(working)
{ } { }
@ -101,28 +101,28 @@ public:
{ } { }
}; };
class MsgConfigureSDRdaemonSinkChunkCorrection : public Message { class MsgConfigureRemoteOutputChunkCorrection : public Message {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
public: public:
int getChunkCorrection() const { return m_chunkCorrection; } int getChunkCorrection() const { return m_chunkCorrection; }
static MsgConfigureSDRdaemonSinkChunkCorrection* create(int chunkCorrection) static MsgConfigureRemoteOutputChunkCorrection* create(int chunkCorrection)
{ {
return new MsgConfigureSDRdaemonSinkChunkCorrection(chunkCorrection); return new MsgConfigureRemoteOutputChunkCorrection(chunkCorrection);
} }
private: private:
int m_chunkCorrection; int m_chunkCorrection;
MsgConfigureSDRdaemonSinkChunkCorrection(int chunkCorrection) : MsgConfigureRemoteOutputChunkCorrection(int chunkCorrection) :
Message(), Message(),
m_chunkCorrection(chunkCorrection) m_chunkCorrection(chunkCorrection)
{ } { }
}; };
SDRdaemonSinkOutput(DeviceSinkAPI *deviceAPI); RemoteOutput(DeviceSinkAPI *deviceAPI);
virtual ~SDRdaemonSinkOutput(); virtual ~RemoteOutput();
virtual void destroy(); virtual void destroy();
virtual void init(); virtual void init();
@ -167,9 +167,9 @@ public:
private: private:
DeviceSinkAPI *m_deviceAPI; DeviceSinkAPI *m_deviceAPI;
QMutex m_mutex; QMutex m_mutex;
SDRdaemonSinkSettings m_settings; RemoteOutputSettings m_settings;
uint64_t m_centerFrequency; uint64_t m_centerFrequency;
SDRdaemonSinkThread* m_sdrDaemonSinkThread; RemoteOutputThread* m_remoteOutputThread;
QString m_deviceDescription; QString m_deviceDescription;
std::time_t m_startingTimeStamp; std::time_t m_startingTimeStamp;
const QTimer& m_masterTimer; const QTimer& m_masterTimer;
@ -189,13 +189,13 @@ private:
int m_chunkSizeCorrection; int m_chunkSizeCorrection;
static const uint32_t NbSamplesForRateCorrection; static const uint32_t NbSamplesForRateCorrection;
void applySettings(const SDRdaemonSinkSettings& settings, bool force = false); void applySettings(const RemoteOutputSettings& settings, bool force = false);
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const SDRdaemonSinkSettings& settings); void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const RemoteOutputSettings& settings);
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response); void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
void analyzeApiReply(const QJsonObject& jsonObject, const QString& answer); void analyzeApiReply(const QJsonObject& jsonObject, const QString& answer);
void sampleRateCorrection(double remoteTimeDeltaUs, double timeDeltaUs, uint32_t remoteSampleCount, uint32_t sampleCount); void sampleRateCorrection(double remoteTimeDeltaUs, double timeDeltaUs, uint32_t remoteSampleCount, uint32_t sampleCount);
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const SDRdaemonSinkSettings& settings, bool force); void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const RemoteOutputSettings& settings, bool force);
void webapiReverseSendStartStop(bool start); void webapiReverseSendStartStop(bool start);
private slots: private slots:
@ -203,4 +203,4 @@ private slots:
void networkManagerFinished(QNetworkReply *reply); void networkManagerFinished(QNetworkReply *reply);
}; };
#endif // INCLUDE_SDRDAEMONSINKOUTPUT_H #endif // INCLUDE_REMOTEOUTPUT_H

Wyświetl plik

@ -9,7 +9,7 @@ CONFIG += plugin
QT += core gui widgets multimedia network opengl QT += core gui widgets multimedia network opengl
TARGET = outputsdrdaemonsink TARGET = remoteoutput
CONFIG(MINGW32):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(MINGW32):LIBCM256CCSRC = "C:\softs\cm256cc"
CONFIG(MSVC):LIBCM256CCSRC = "C:\softs\cm256cc" CONFIG(MSVC):LIBCM256CCSRC = "C:\softs\cm256cc"
@ -38,23 +38,23 @@ CONFIG(MINGW32):INCLUDEPATH += "C:\softs\boost_1_66_0"
CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0" CONFIG(MSVC):INCLUDEPATH += "C:\softs\boost_1_66_0"
CONFIG(macx):INCLUDEPATH += "../../../boost_1_69_0" CONFIG(macx):INCLUDEPATH += "../../../boost_1_69_0"
SOURCES += sdrdaemonsinkthread.cpp\ SOURCES += remoteoutputthread.cpp\
sdrdaemonsinkgui.cpp\ remoteoutputgui.cpp\
sdrdaemonsinkoutput.cpp\ remtoeoutput.cpp\
sdrdaemonsinksettings.cpp\ remtoeoutputsettings.cpp\
sdrdaemonsinkplugin.cpp\ remoteoutputplugin.cpp\
udpsinkfec.cpp\ udpsinkfec.cpp\
udpsinkfecworker.cpp udpsinkfecworker.cpp
HEADERS += sdrdaemonsinkthread.h\ HEADERS += remoteoutputthread.h\
sdrdaemonsinkgui.h\ remoteoutputgui.h\
sdrdaemonsinkoutput.h\ remtoeoutput.h\
sdrdaemonsinksettings.h\ remtoeoutputsettings.h\
sdrdaemonsinkplugin.h\ remoteoutputplugin.h\
udpsinkfec.h\ udpsinkfec.h\
udpsinkfecworker.h udpsinkfecworker.h
FORMS += sdrdaemonsinkgui.ui FORMS += remoteoutputgui.ui
LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase
LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui

Wyświetl plik

@ -26,7 +26,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "ui_sdrdaemonsinkgui.h" #include "ui_remoteoutputgui.h"
#include "plugin/pluginapi.h" #include "plugin/pluginapi.h"
#include "gui/colormapper.h" #include "gui/colormapper.h"
#include "gui/glspectrum.h" #include "gui/glspectrum.h"
@ -39,13 +39,15 @@
#include "device/devicesinkapi.h" #include "device/devicesinkapi.h"
#include "device/deviceuiset.h" #include "device/deviceuiset.h"
#include "channel/sdrdaemondatablock.h" #include "remoteoutputgui.h"
#include "udpsinkfec.h"
#include "sdrdaemonsinkgui.h"
SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent) : #include <channel/remotedatablock.h>
#include "udpsinkfec.h"
RemoteOutputSinkGui::RemoteOutputSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
QWidget(parent), QWidget(parent),
ui(new Ui::SDRdaemonSinkGui), ui(new Ui::RemoteOutputGui),
m_deviceUISet(deviceUISet), m_deviceUISet(deviceUISet),
m_settings(), m_settings(),
m_deviceSampleSink(0), m_deviceSampleSink(0),
@ -83,7 +85,7 @@ SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(500); m_statusTimer.start(500);
m_deviceSampleSink = (SDRdaemonSinkOutput*) m_deviceUISet->m_deviceSinkAPI->getSampleSink(); m_deviceSampleSink = (RemoteOutput*) m_deviceUISet->m_deviceSinkAPI->getSampleSink();
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
@ -103,34 +105,34 @@ SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
sendSettings(); sendSettings();
} }
SDRdaemonSinkGui::~SDRdaemonSinkGui() RemoteOutputSinkGui::~RemoteOutputSinkGui()
{ {
disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
delete m_networkManager; delete m_networkManager;
delete ui; delete ui;
} }
void SDRdaemonSinkGui::blockApplySettings(bool block) void RemoteOutputSinkGui::blockApplySettings(bool block)
{ {
m_doApplySettings = !block; m_doApplySettings = !block;
} }
void SDRdaemonSinkGui::destroy() void RemoteOutputSinkGui::destroy()
{ {
delete this; delete this;
} }
void SDRdaemonSinkGui::setName(const QString& name) void RemoteOutputSinkGui::setName(const QString& name)
{ {
setObjectName(name); setObjectName(name);
} }
QString SDRdaemonSinkGui::getName() const QString RemoteOutputSinkGui::getName() const
{ {
return objectName(); return objectName();
} }
void SDRdaemonSinkGui::resetToDefaults() void RemoteOutputSinkGui::resetToDefaults()
{ {
blockApplySettings(true); blockApplySettings(true);
m_settings.resetToDefaults(); m_settings.resetToDefaults();
@ -139,12 +141,12 @@ void SDRdaemonSinkGui::resetToDefaults()
sendSettings(); sendSettings();
} }
QByteArray SDRdaemonSinkGui::serialize() const QByteArray RemoteOutputSinkGui::serialize() const
{ {
return m_settings.serialize(); return m_settings.serialize();
} }
bool SDRdaemonSinkGui::deserialize(const QByteArray& data) bool RemoteOutputSinkGui::deserialize(const QByteArray& data)
{ {
blockApplySettings(true); blockApplySettings(true);
@ -163,20 +165,20 @@ bool SDRdaemonSinkGui::deserialize(const QByteArray& data)
} }
} }
bool SDRdaemonSinkGui::handleMessage(const Message& message) bool RemoteOutputSinkGui::handleMessage(const Message& message)
{ {
if (SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink::match(message)) if (RemoteOutput::MsgConfigureRemoteOutput::match(message))
{ {
const SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink& cfg = (SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink&) message; const RemoteOutput::MsgConfigureRemoteOutput& cfg = (RemoteOutput::MsgConfigureRemoteOutput&) message;
m_settings = cfg.getSettings(); m_settings = cfg.getSettings();
blockApplySettings(true); blockApplySettings(true);
displaySettings(); displaySettings();
blockApplySettings(false); blockApplySettings(false);
return true; return true;
} }
else if (SDRdaemonSinkOutput::MsgStartStop::match(message)) else if (RemoteOutput::MsgStartStop::match(message))
{ {
SDRdaemonSinkOutput::MsgStartStop& notif = (SDRdaemonSinkOutput::MsgStartStop&) message; RemoteOutput::MsgStartStop& notif = (RemoteOutput::MsgStartStop&) message;
blockApplySettings(true); blockApplySettings(true);
ui->startStop->setChecked(notif.getStartStop()); ui->startStop->setChecked(notif.getStartStop());
blockApplySettings(false); blockApplySettings(false);
@ -188,7 +190,7 @@ bool SDRdaemonSinkGui::handleMessage(const Message& message)
} }
} }
void SDRdaemonSinkGui::handleInputMessages() void RemoteOutputSinkGui::handleInputMessages()
{ {
Message* message; Message* message;
@ -198,7 +200,7 @@ void SDRdaemonSinkGui::handleInputMessages()
{ {
DSPSignalNotification* notif = (DSPSignalNotification*) message; DSPSignalNotification* notif = (DSPSignalNotification*) message;
m_sampleRate = notif->getSampleRate(); m_sampleRate = notif->getSampleRate();
qDebug("SDRdaemonSinkGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency()); qDebug("RemoteOutputSinkGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
updateSampleRate(); updateSampleRate();
delete message; delete message;
@ -212,20 +214,20 @@ void SDRdaemonSinkGui::handleInputMessages()
} }
} }
void SDRdaemonSinkGui::updateSampleRate() void RemoteOutputSinkGui::updateSampleRate()
{ {
m_deviceUISet->getSpectrum()->setSampleRate(m_sampleRate); m_deviceUISet->getSpectrum()->setSampleRate(m_sampleRate);
ui->deviceRateText->setText(tr("%1k").arg((float)(m_sampleRate) / 1000)); ui->deviceRateText->setText(tr("%1k").arg((float)(m_sampleRate) / 1000));
} }
void SDRdaemonSinkGui::updateTxDelayTooltip() void RemoteOutputSinkGui::updateTxDelayTooltip()
{ {
int samplesPerBlock = SDRDaemonNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); int samplesPerBlock = RemoteNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8);
double delay = ((127*samplesPerBlock*m_settings.m_txDelay) / m_settings.m_sampleRate)/(128 + m_settings.m_nbFECBlocks); double delay = ((127*samplesPerBlock*m_settings.m_txDelay) / m_settings.m_sampleRate)/(128 + m_settings.m_nbFECBlocks);
ui->txDelayText->setToolTip(tr("%1 us").arg(QString::number(delay*1e6, 'f', 0))); ui->txDelayText->setToolTip(tr("%1 us").arg(QString::number(delay*1e6, 'f', 0)));
} }
void SDRdaemonSinkGui::displaySettings() void RemoteOutputSinkGui::displaySettings()
{ {
blockApplySettings(true); blockApplySettings(true);
ui->centerFrequency->setValue(m_deviceCenterFrequency / 1000); ui->centerFrequency->setValue(m_deviceCenterFrequency / 1000);
@ -247,23 +249,23 @@ void SDRdaemonSinkGui::displaySettings()
blockApplySettings(false); blockApplySettings(false);
} }
void SDRdaemonSinkGui::sendSettings() void RemoteOutputSinkGui::sendSettings()
{ {
if(!m_updateTimer.isActive()) if(!m_updateTimer.isActive())
m_updateTimer.start(100); m_updateTimer.start(100);
} }
void SDRdaemonSinkGui::updateHardware() void RemoteOutputSinkGui::updateHardware()
{ {
qDebug() << "SDRdaemonSinkGui::updateHardware"; qDebug() << "RemoteOutputSinkGui::updateHardware";
SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink* message = SDRdaemonSinkOutput::MsgConfigureSDRdaemonSink::create(m_settings, m_forceSettings); RemoteOutput::MsgConfigureRemoteOutput* message = RemoteOutput::MsgConfigureRemoteOutput::create(m_settings, m_forceSettings);
m_deviceSampleSink->getInputMessageQueue()->push(message); m_deviceSampleSink->getInputMessageQueue()->push(message);
m_forceSettings = false; m_forceSettings = false;
m_updateTimer.stop(); m_updateTimer.stop();
} }
void SDRdaemonSinkGui::updateStatus() void RemoteOutputSinkGui::updateStatus()
{ {
int state = m_deviceUISet->m_deviceSinkAPI->state(); int state = m_deviceUISet->m_deviceSinkAPI->state();
@ -292,14 +294,14 @@ void SDRdaemonSinkGui::updateStatus()
} }
} }
void SDRdaemonSinkGui::on_sampleRate_changed(quint64 value) void RemoteOutputSinkGui::on_sampleRate_changed(quint64 value)
{ {
m_settings.m_sampleRate = value; m_settings.m_sampleRate = value;
updateTxDelayTooltip(); updateTxDelayTooltip();
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_txDelay_valueChanged(int value) void RemoteOutputSinkGui::on_txDelay_valueChanged(int value)
{ {
m_settings.m_txDelay = value / 100.0; m_settings.m_txDelay = value / 100.0;
ui->txDelayText->setText(tr("%1").arg(value)); ui->txDelayText->setText(tr("%1").arg(value));
@ -307,7 +309,7 @@ void SDRdaemonSinkGui::on_txDelay_valueChanged(int value)
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_nbFECBlocks_valueChanged(int value) void RemoteOutputSinkGui::on_nbFECBlocks_valueChanged(int value)
{ {
m_settings.m_nbFECBlocks = value; m_settings.m_nbFECBlocks = value;
int nbOriginalBlocks = 128; int nbOriginalBlocks = 128;
@ -319,7 +321,7 @@ void SDRdaemonSinkGui::on_nbFECBlocks_valueChanged(int value)
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_deviceIndex_returnPressed() void RemoteOutputSinkGui::on_deviceIndex_returnPressed()
{ {
bool dataOk; bool dataOk;
int deviceIndex = ui->deviceIndex->text().toInt(&dataOk); int deviceIndex = ui->deviceIndex->text().toInt(&dataOk);
@ -333,7 +335,7 @@ void SDRdaemonSinkGui::on_deviceIndex_returnPressed()
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_channelIndex_returnPressed() void RemoteOutputSinkGui::on_channelIndex_returnPressed()
{ {
bool dataOk; bool dataOk;
int channelIndex = ui->channelIndex->text().toInt(&dataOk); int channelIndex = ui->channelIndex->text().toInt(&dataOk);
@ -347,7 +349,7 @@ void SDRdaemonSinkGui::on_channelIndex_returnPressed()
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_apiAddress_returnPressed() void RemoteOutputSinkGui::on_apiAddress_returnPressed()
{ {
m_settings.m_apiAddress = ui->apiAddress->text(); m_settings.m_apiAddress = ui->apiAddress->text();
sendSettings(); sendSettings();
@ -357,7 +359,7 @@ void SDRdaemonSinkGui::on_apiAddress_returnPressed()
m_networkManager->get(m_networkRequest); m_networkManager->get(m_networkRequest);
} }
void SDRdaemonSinkGui::on_apiPort_returnPressed() void RemoteOutputSinkGui::on_apiPort_returnPressed()
{ {
bool dataOk; bool dataOk;
int apiPort = ui->apiPort->text().toInt(&dataOk); int apiPort = ui->apiPort->text().toInt(&dataOk);
@ -375,13 +377,13 @@ void SDRdaemonSinkGui::on_apiPort_returnPressed()
m_networkManager->get(m_networkRequest); m_networkManager->get(m_networkRequest);
} }
void SDRdaemonSinkGui::on_dataAddress_returnPressed() void RemoteOutputSinkGui::on_dataAddress_returnPressed()
{ {
m_settings.m_dataAddress = ui->dataAddress->text(); m_settings.m_dataAddress = ui->dataAddress->text();
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_dataPort_returnPressed() void RemoteOutputSinkGui::on_dataPort_returnPressed()
{ {
bool dataOk; bool dataOk;
int dataPort = ui->dataPort->text().toInt(&dataOk); int dataPort = ui->dataPort->text().toInt(&dataOk);
@ -395,7 +397,7 @@ void SDRdaemonSinkGui::on_dataPort_returnPressed()
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_apiApplyButton_clicked(bool checked) void RemoteOutputSinkGui::on_apiApplyButton_clicked(bool checked)
{ {
(void) checked; (void) checked;
m_settings.m_apiAddress = ui->apiAddress->text(); m_settings.m_apiAddress = ui->apiAddress->text();
@ -415,7 +417,7 @@ void SDRdaemonSinkGui::on_apiApplyButton_clicked(bool checked)
m_networkManager->get(m_networkRequest); m_networkManager->get(m_networkRequest);
} }
void SDRdaemonSinkGui::on_dataApplyButton_clicked(bool checked) void RemoteOutputSinkGui::on_dataApplyButton_clicked(bool checked)
{ {
(void) checked; (void) checked;
m_settings.m_dataAddress = ui->dataAddress->text(); m_settings.m_dataAddress = ui->dataAddress->text();
@ -431,16 +433,16 @@ void SDRdaemonSinkGui::on_dataApplyButton_clicked(bool checked)
sendSettings(); sendSettings();
} }
void SDRdaemonSinkGui::on_startStop_toggled(bool checked) void RemoteOutputSinkGui::on_startStop_toggled(bool checked)
{ {
if (m_doApplySettings) if (m_doApplySettings)
{ {
SDRdaemonSinkOutput::MsgStartStop *message = SDRdaemonSinkOutput::MsgStartStop::create(checked); RemoteOutput::MsgStartStop *message = RemoteOutput::MsgStartStop::create(checked);
m_deviceSampleSink->getInputMessageQueue()->push(message); m_deviceSampleSink->getInputMessageQueue()->push(message);
} }
} }
void SDRdaemonSinkGui::on_eventCountsReset_clicked(bool checked) void RemoteOutputSinkGui::on_eventCountsReset_clicked(bool checked)
{ {
(void) checked; (void) checked;
m_countUnrecoverable = 0; m_countUnrecoverable = 0;
@ -450,7 +452,7 @@ void SDRdaemonSinkGui::on_eventCountsReset_clicked(bool checked)
displayEventTimer(); displayEventTimer();
} }
void SDRdaemonSinkGui::displayEventCounts() void RemoteOutputSinkGui::displayEventCounts()
{ {
QString nstr = QString("%1").arg(m_countUnrecoverable, 3, 10, QChar('0')); QString nstr = QString("%1").arg(m_countUnrecoverable, 3, 10, QChar('0'));
ui->eventUnrecText->setText(nstr); ui->eventUnrecText->setText(nstr);
@ -458,7 +460,7 @@ void SDRdaemonSinkGui::displayEventCounts()
ui->eventRecText->setText(nstr); ui->eventRecText->setText(nstr);
} }
void SDRdaemonSinkGui::displayEventStatus(int recoverableCount, int unrecoverableCount) void RemoteOutputSinkGui::displayEventStatus(int recoverableCount, int unrecoverableCount)
{ {
if (unrecoverableCount == 0) if (unrecoverableCount == 0)
@ -475,7 +477,7 @@ void SDRdaemonSinkGui::displayEventStatus(int recoverableCount, int unrecoverabl
} }
} }
void SDRdaemonSinkGui::displayEventTimer() void RemoteOutputSinkGui::displayEventTimer()
{ {
int elapsedTimeMillis = m_time.elapsed(); int elapsedTimeMillis = m_time.elapsed();
QTime recordLength(0, 0, 0, 0); QTime recordLength(0, 0, 0, 0);
@ -484,7 +486,7 @@ void SDRdaemonSinkGui::displayEventTimer()
ui->eventCountsTimeText->setText(s_time); ui->eventCountsTimeText->setText(s_time);
} }
void SDRdaemonSinkGui::tick() void RemoteOutputSinkGui::tick()
{ {
if (++m_tickCount == 20) // once per second if (++m_tickCount == 20) // once per second
{ {
@ -504,7 +506,7 @@ void SDRdaemonSinkGui::tick()
} }
} }
void SDRdaemonSinkGui::networkManagerFinished(QNetworkReply *reply) void RemoteOutputSinkGui::networkManagerFinished(QNetworkReply *reply)
{ {
if (reply->error()) if (reply->error())
{ {
@ -532,7 +534,7 @@ void SDRdaemonSinkGui::networkManagerFinished(QNetworkReply *reply)
ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }"); ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
QString errorMsg = QString("Reply JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset); QString errorMsg = QString("Reply JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset);
ui->statusText->setText(QString("JSON error. See log")); ui->statusText->setText(QString("JSON error. See log"));
qInfo().noquote() << "SDRdaemonSinkGui::networkManagerFinished" << errorMsg; qInfo().noquote() << "RemoteOutputSinkGui::networkManagerFinished" << errorMsg;
} }
} }
catch (const std::exception& ex) catch (const std::exception& ex)
@ -540,11 +542,11 @@ void SDRdaemonSinkGui::networkManagerFinished(QNetworkReply *reply)
ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }"); ui->apiAddressLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
QString errorMsg = QString("Error parsing request: ") + ex.what(); QString errorMsg = QString("Error parsing request: ") + ex.what();
ui->statusText->setText("Error parsing request. See log for details"); ui->statusText->setText("Error parsing request. See log for details");
qInfo().noquote() << "SDRdaemonSinkGui::networkManagerFinished" << errorMsg; qInfo().noquote() << "RemoteOutputSinkGui::networkManagerFinished" << errorMsg;
} }
} }
void SDRdaemonSinkGui::analyzeApiReply(const QJsonObject& jsonObject) void RemoteOutputSinkGui::analyzeApiReply(const QJsonObject& jsonObject)
{ {
QString infoLine; QString infoLine;
@ -629,7 +631,7 @@ void SDRdaemonSinkGui::analyzeApiReply(const QJsonObject& jsonObject)
} }
} }
void SDRdaemonSinkGui::openDeviceSettingsDialog(const QPoint& p) void RemoteOutputSinkGui::openDeviceSettingsDialog(const QPoint& p)
{ {
BasicDeviceSettingsDialog dialog(this); BasicDeviceSettingsDialog dialog(this);
dialog.setUseReverseAPI(m_settings.m_useReverseAPI); dialog.setUseReverseAPI(m_settings.m_useReverseAPI);

Wyświetl plik

@ -14,8 +14,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_SDRDAEMONSINKGUI_H #ifndef INCLUDE_REMOTEOUTPUTGUI_H
#define INCLUDE_SDRDAEMONSINKGUI_H #define INCLUDE_REMOTEOUTPUTGUI_H
#include <stdint.h> #include <stdint.h>
@ -28,8 +28,8 @@
#include "util/messagequeue.h" #include "util/messagequeue.h"
#include "util/limitedcounter.h" #include "util/limitedcounter.h"
#include "sdrdaemonsinksettings.h" #include "remoteoutput.h"
#include "sdrdaemonsinkoutput.h" #include "remoteoutputsettings.h"
class QNetworkAccessManager; class QNetworkAccessManager;
class QNetworkReply; class QNetworkReply;
@ -38,12 +38,12 @@ class DeviceSampleSink;
class DeviceUISet; class DeviceUISet;
namespace Ui { namespace Ui {
class SDRdaemonSinkGui; class RemoteOutputGui;
} }
class SDRdaemonSinkExpAvg { class RemoteOutputExpAvg {
public: public:
SDRdaemonSinkExpAvg(float alpha) : RemoteOutputExpAvg(float alpha) :
m_alpha(alpha), m_alpha(alpha),
m_start(true), m_start(true),
m_s(0) m_s(0)
@ -68,12 +68,12 @@ private:
float m_s; float m_s;
}; };
class SDRdaemonSinkGui : public QWidget, public PluginInstanceGUI { class RemoteOutputSinkGui : public QWidget, public PluginInstanceGUI {
Q_OBJECT Q_OBJECT
public: public:
explicit SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent = 0); explicit RemoteOutputSinkGui(DeviceUISet *deviceUISet, QWidget* parent = 0);
virtual ~SDRdaemonSinkGui(); virtual ~RemoteOutputSinkGui();
virtual void destroy(); virtual void destroy();
void setName(const QString& name); void setName(const QString& name);
@ -88,11 +88,11 @@ public:
virtual bool handleMessage(const Message& message); virtual bool handleMessage(const Message& message);
private: private:
Ui::SDRdaemonSinkGui* ui; Ui::RemoteOutputGui* ui;
DeviceUISet* m_deviceUISet; DeviceUISet* m_deviceUISet;
SDRdaemonSinkSettings m_settings; //!< current settings RemoteOutputSettings m_settings; //!< current settings
SDRdaemonSinkSettings m_controlSettings; //!< settings last sent to device via control port RemoteOutputSettings m_controlSettings; //!< settings last sent to device via control port
QTimer m_updateTimer; QTimer m_updateTimer;
QTimer m_statusTimer; QTimer m_statusTimer;
DeviceSampleSink* m_deviceSampleSink; DeviceSampleSink* m_deviceSampleSink;
@ -157,4 +157,4 @@ private slots:
void openDeviceSettingsDialog(const QPoint& p); void openDeviceSettingsDialog(const QPoint& p);
}; };
#endif // INCLUDE_FILESINKGUI_H #endif // INCLUDE_REMOTEOUTPUTGUI_H

Wyświetl plik

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>SDRdaemonSinkGui</class> <class>RemoteOutputGui</class>
<widget class="QWidget" name="SDRdaemonSinkGui"> <widget class="QWidget" name="RemoteOutputGui">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -32,7 +32,7 @@
</font> </font>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>SDRdaemon Sink</string> <string>Remote Output</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing"> <property name="spacing">

Wyświetl plik

@ -21,45 +21,45 @@
#include "device/devicesinkapi.h" #include "device/devicesinkapi.h"
#ifdef SERVER_MODE #ifdef SERVER_MODE
#include "sdrdaemonsinkoutput.h" #include "remoteoutput.h"
#else #else
#include "sdrdaemonsinkgui.h" #include "remoteoutputgui.h"
#endif #endif
#include "sdrdaemonsinkplugin.h" #include "remoteoutputplugin.h"
const PluginDescriptor SDRdaemonSinkPlugin::m_pluginDescriptor = { const PluginDescriptor RemoteOutputPlugin::m_pluginDescriptor = {
QString("SDRdaemon sink output"), QString("Remote output"),
QString("4.4.1"), QString("4.4.3"),
QString("(c) Edouard Griffiths, F4EXB"), QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"), QString("https://github.com/f4exb/sdrangel"),
true, true,
QString("https://github.com/f4exb/sdrangel") QString("https://github.com/f4exb/sdrangel")
}; };
const QString SDRdaemonSinkPlugin::m_hardwareID = "SDRdaemonSink"; const QString RemoteOutputPlugin::m_hardwareID = "RemoteOutput";
const QString SDRdaemonSinkPlugin::m_deviceTypeID = SDRDAEMONSINK_DEVICE_TYPE_ID; const QString RemoteOutputPlugin::m_deviceTypeID = REMOTEOUTPUT_DEVICE_TYPE_ID;
SDRdaemonSinkPlugin::SDRdaemonSinkPlugin(QObject* parent) : RemoteOutputPlugin::RemoteOutputPlugin(QObject* parent) :
QObject(parent) QObject(parent)
{ {
} }
const PluginDescriptor& SDRdaemonSinkPlugin::getPluginDescriptor() const const PluginDescriptor& RemoteOutputPlugin::getPluginDescriptor() const
{ {
return m_pluginDescriptor; return m_pluginDescriptor;
} }
void SDRdaemonSinkPlugin::initPlugin(PluginAPI* pluginAPI) void RemoteOutputPlugin::initPlugin(PluginAPI* pluginAPI)
{ {
pluginAPI->registerSampleSink(m_deviceTypeID, this); pluginAPI->registerSampleSink(m_deviceTypeID, this);
} }
PluginInterface::SamplingDevices SDRdaemonSinkPlugin::enumSampleSinks() PluginInterface::SamplingDevices RemoteOutputPlugin::enumSampleSinks()
{ {
SamplingDevices result; SamplingDevices result;
result.append(SamplingDevice( result.append(SamplingDevice(
"SDRdaemonSink", "RemoteOutput",
m_hardwareID, m_hardwareID,
m_deviceTypeID, m_deviceTypeID,
QString::null, QString::null,
@ -73,7 +73,7 @@ PluginInterface::SamplingDevices SDRdaemonSinkPlugin::enumSampleSinks()
} }
#ifdef SERVER_MODE #ifdef SERVER_MODE
PluginInstanceGUI* SDRdaemonSinkPlugin::createSampleSinkPluginInstanceGUI( PluginInstanceGUI* RemoteOutputPlugin::createSampleSinkPluginInstanceGUI(
const QString& sinkId __attribute((unused)), const QString& sinkId __attribute((unused)),
QWidget **widget __attribute((unused)), QWidget **widget __attribute((unused)),
DeviceUISet *deviceUISet __attribute((unused))) DeviceUISet *deviceUISet __attribute((unused)))
@ -81,14 +81,14 @@ PluginInstanceGUI* SDRdaemonSinkPlugin::createSampleSinkPluginInstanceGUI(
return 0; return 0;
} }
#else #else
PluginInstanceGUI* SDRdaemonSinkPlugin::createSampleSinkPluginInstanceGUI( PluginInstanceGUI* RemoteOutputPlugin::createSampleSinkPluginInstanceGUI(
const QString& sinkId, const QString& sinkId,
QWidget **widget, QWidget **widget,
DeviceUISet *deviceUISet) DeviceUISet *deviceUISet)
{ {
if(sinkId == m_deviceTypeID) if(sinkId == m_deviceTypeID)
{ {
SDRdaemonSinkGui* gui = new SDRdaemonSinkGui(deviceUISet); RemoteOutputSinkGui* gui = new RemoteOutputSinkGui(deviceUISet);
*widget = gui; *widget = gui;
return gui; return gui;
} }
@ -99,11 +99,11 @@ PluginInstanceGUI* SDRdaemonSinkPlugin::createSampleSinkPluginInstanceGUI(
} }
#endif #endif
DeviceSampleSink* SDRdaemonSinkPlugin::createSampleSinkPluginInstanceOutput(const QString& sinkId, DeviceSinkAPI *deviceAPI) DeviceSampleSink* RemoteOutputPlugin::createSampleSinkPluginInstanceOutput(const QString& sinkId, DeviceSinkAPI *deviceAPI)
{ {
if(sinkId == m_deviceTypeID) if(sinkId == m_deviceTypeID)
{ {
SDRdaemonSinkOutput* output = new SDRdaemonSinkOutput(deviceAPI); RemoteOutput* output = new RemoteOutput(deviceAPI);
return output; return output;
} }
else else

Wyświetl plik

@ -14,24 +14,24 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_SDRDAEMONSINKPLUGIN_H #ifndef INCLUDE_REMOTEOUTPUTPLUGIN_H
#define INCLUDE_SDRDAEMONSINKPLUGIN_H #define INCLUDE_REMOTEOUTPUTPLUGIN_H
#include <QObject> #include <QObject>
#include "plugin/plugininterface.h" #include "plugin/plugininterface.h"
#define SDRDAEMONSINK_DEVICE_TYPE_ID "sdrangel.samplesink.sdrdaemonsink" #define REMOTEOUTPUT_DEVICE_TYPE_ID "sdrangel.samplesink.remoteoutput"
class PluginAPI; class PluginAPI;
class DeviceSinkAPI; class DeviceSinkAPI;
class SDRdaemonSinkPlugin : public QObject, public PluginInterface { class RemoteOutputPlugin : public QObject, public PluginInterface {
Q_OBJECT Q_OBJECT
Q_INTERFACES(PluginInterface) Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID SDRDAEMONSINK_DEVICE_TYPE_ID) Q_PLUGIN_METADATA(IID REMOTEOUTPUT_DEVICE_TYPE_ID)
public: public:
explicit SDRdaemonSinkPlugin(QObject* parent = NULL); explicit RemoteOutputPlugin(QObject* parent = NULL);
const PluginDescriptor& getPluginDescriptor() const; const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI); void initPlugin(PluginAPI* pluginAPI);
@ -50,4 +50,4 @@ private:
static const PluginDescriptor m_pluginDescriptor; static const PluginDescriptor m_pluginDescriptor;
}; };
#endif // INCLUDE_SDRDAEMONSINKPLUGIN_H #endif // INCLUDE_REMOTEOUTPUTPLUGIN_H

Wyświetl plik

@ -15,14 +15,14 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "sdrdaemonsinksettings.h" #include "remoteoutputsettings.h"
SDRdaemonSinkSettings::SDRdaemonSinkSettings() RemoteOutputSettings::RemoteOutputSettings()
{ {
resetToDefaults(); resetToDefaults();
} }
void SDRdaemonSinkSettings::resetToDefaults() void RemoteOutputSettings::resetToDefaults()
{ {
m_centerFrequency = 435000*1000; m_centerFrequency = 435000*1000;
m_sampleRate = 48000; m_sampleRate = 48000;
@ -40,7 +40,7 @@ void SDRdaemonSinkSettings::resetToDefaults()
m_reverseAPIDeviceIndex = 0; m_reverseAPIDeviceIndex = 0;
} }
QByteArray SDRdaemonSinkSettings::serialize() const QByteArray RemoteOutputSettings::serialize() const
{ {
SimpleSerializer s(1); SimpleSerializer s(1);
@ -62,7 +62,7 @@ QByteArray SDRdaemonSinkSettings::serialize() const
return s.final(); return s.final();
} }
bool SDRdaemonSinkSettings::deserialize(const QByteArray& data) bool RemoteOutputSettings::deserialize(const QByteArray& data)
{ {
SimpleDeserializer d(data); SimpleDeserializer d(data);

Wyświetl plik

@ -14,12 +14,13 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_SDRDAEMONSINK_SDRDAEMONSINKSETTINGS_H_ #ifndef PLUGINS_REMOTEOUTPUT_REMOTEOUTPUTSETTINGS_H_
#define PLUGINS_SAMPLESINK_SDRDAEMONSINK_SDRDAEMONSINKSETTINGS_H_ #define PLUGINS_REMOTEOUTPUT_REMOTEOUTPUTSETTINGS_H_
#include <QByteArray> #include <QByteArray>
#include <QString>
struct SDRdaemonSinkSettings { struct RemoteOutputSettings {
quint64 m_centerFrequency; quint64 m_centerFrequency;
quint32 m_sampleRate; quint32 m_sampleRate;
float m_txDelay; float m_txDelay;
@ -35,10 +36,10 @@ struct SDRdaemonSinkSettings {
uint16_t m_reverseAPIPort; uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex; uint16_t m_reverseAPIDeviceIndex;
SDRdaemonSinkSettings(); RemoteOutputSettings();
void resetToDefaults(); void resetToDefaults();
QByteArray serialize() const; QByteArray serialize() const;
bool deserialize(const QByteArray& data); bool deserialize(const QByteArray& data);
}; };
#endif /* PLUGINS_SAMPLESINK_SDRDAEMONSINK_SDRDAEMONSINKSETTINGS_H_ */ #endif /* PLUGINS_REMOTEOUTPUT_REMOTEOUTPUTSETTINGS_H_ */

Wyświetl plik

@ -22,9 +22,9 @@
#include "dsp/samplesourcefifo.h" #include "dsp/samplesourcefifo.h"
#include "util/timeutil.h" #include "util/timeutil.h"
#include "sdrdaemonsinkthread.h" #include "remoteoutputthread.h"
SDRdaemonSinkThread::SDRdaemonSinkThread(SampleSourceFifo* sampleFifo, QObject* parent) : RemoteOutputThread::RemoteOutputThread(SampleSourceFifo* sampleFifo, QObject* parent) :
QThread(parent), QThread(parent),
m_running(false), m_running(false),
m_samplesChunkSize(0), m_samplesChunkSize(0),
@ -32,22 +32,22 @@ SDRdaemonSinkThread::SDRdaemonSinkThread(SampleSourceFifo* sampleFifo, QObject*
m_samplesCount(0), m_samplesCount(0),
m_chunkCorrection(0), m_chunkCorrection(0),
m_samplerate(0), m_samplerate(0),
m_throttlems(SDRDAEMONSINK_THROTTLE_MS), m_throttlems(REMOTEOUTPUT_THROTTLE_MS),
m_maxThrottlems(50), m_maxThrottlems(50),
m_throttleToggle(false) m_throttleToggle(false)
{ {
} }
SDRdaemonSinkThread::~SDRdaemonSinkThread() RemoteOutputThread::~RemoteOutputThread()
{ {
if (m_running) { if (m_running) {
stopWork(); stopWork();
} }
} }
void SDRdaemonSinkThread::startWork() void RemoteOutputThread::startWork()
{ {
qDebug() << "SDRdaemonSinkThread::startWork: "; qDebug() << "RemoteOutputThread::startWork: ";
m_udpSinkFEC.start(); m_udpSinkFEC.start();
m_maxThrottlems = 0; m_maxThrottlems = 0;
m_startWaitMutex.lock(); m_startWaitMutex.lock();
@ -58,19 +58,19 @@ void SDRdaemonSinkThread::startWork()
m_startWaitMutex.unlock(); m_startWaitMutex.unlock();
} }
void SDRdaemonSinkThread::stopWork() void RemoteOutputThread::stopWork()
{ {
qDebug() << "SDRdaemonSinkThread::stopWork"; qDebug() << "RemoteOutputThread::stopWork";
m_running = false; m_running = false;
wait(); wait();
m_udpSinkFEC.stop(); m_udpSinkFEC.stop();
} }
void SDRdaemonSinkThread::setSamplerate(int samplerate) void RemoteOutputThread::setSamplerate(int samplerate)
{ {
if (samplerate != m_samplerate) if (samplerate != m_samplerate)
{ {
qDebug() << "SDRdaemonSinkThread::setSamplerate:" qDebug() << "RemoteOutputThread::setSamplerate:"
<< " new:" << samplerate << " new:" << samplerate
<< " old:" << m_samplerate; << " old:" << m_samplerate;
@ -97,7 +97,7 @@ void SDRdaemonSinkThread::setSamplerate(int samplerate)
} }
} }
void SDRdaemonSinkThread::run() void RemoteOutputThread::run()
{ {
m_running = true; m_running = true;
m_startWaiter.wakeAll(); m_startWaiter.wakeAll();
@ -110,13 +110,13 @@ void SDRdaemonSinkThread::run()
m_running = false; m_running = false;
} }
void SDRdaemonSinkThread::connectTimer(const QTimer& timer) void RemoteOutputThread::connectTimer(const QTimer& timer)
{ {
qDebug() << "SDRdaemonSinkThread::connectTimer"; qDebug() << "RemoteOutputThread::connectTimer";
connect(&timer, SIGNAL(timeout()), this, SLOT(tick())); connect(&timer, SIGNAL(timeout()), this, SLOT(tick()));
} }
void SDRdaemonSinkThread::tick() void RemoteOutputThread::tick()
{ {
if (m_running) if (m_running)
{ {
@ -140,7 +140,7 @@ void SDRdaemonSinkThread::tick()
} }
} }
uint32_t SDRdaemonSinkThread::getSamplesCount(uint64_t& ts_usecs) const uint32_t RemoteOutputThread::getSamplesCount(uint64_t& ts_usecs) const
{ {
ts_usecs = TimeUtil::nowus(); ts_usecs = TimeUtil::nowus();
return m_samplesCount; return m_samplesCount;

Wyświetl plik

@ -14,8 +14,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_SDRDAEMONSINKTHREAD_H #ifndef INCLUDE_REMOTEOUTPUTTHREAD_H
#define INCLUDE_SDRDAEMONSINKTHREAD_H #define INCLUDE_REMOTEOUTPUTTHREAD_H
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -33,17 +33,17 @@
#include "udpsinkfec.h" #include "udpsinkfec.h"
#define SDRDAEMONSINK_THROTTLE_MS 50 #define REMOTEOUTPUT_THROTTLE_MS 50
class SampleSourceFifo; class SampleSourceFifo;
struct timeval; struct timeval;
class SDRdaemonSinkThread : public QThread { class RemoteOutputThread : public QThread {
Q_OBJECT Q_OBJECT
public: public:
SDRdaemonSinkThread(SampleSourceFifo* sampleFifo, QObject* parent = 0); RemoteOutputThread(SampleSourceFifo* sampleFifo, QObject* parent = 0);
~SDRdaemonSinkThread(); ~RemoteOutputThread();
void startWork(); void startWork();
void stopWork(); void stopWork();
@ -85,4 +85,4 @@ private slots:
void tick(); void tick();
}; };
#endif // INCLUDE_SDRDAEMONSINKTHREAD_H #endif // INCLUDE_REMOTEOUTPUTTHREAD_H

Wyświetl plik

@ -14,13 +14,15 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include "udpsinkfec.h"
#include <QDebug> #include <QDebug>
#include <boost/crc.hpp> #include <boost/crc.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include "util/timeutil.h" #include "util/timeutil.h"
#include "udpsinkfec.h"
#include "udpsinkfecworker.h" #include "udpsinkfecworker.h"
@ -38,8 +40,8 @@ UDPSinkFEC::UDPSinkFEC() :
m_remoteAddress("127.0.0.1"), m_remoteAddress("127.0.0.1"),
m_remotePort(9090) m_remotePort(9090)
{ {
memset((char *) m_txBlocks, 0, 4*256*sizeof(SDRDaemonSuperBlock)); memset((char *) m_txBlocks, 0, 4*256*sizeof(RemoteSuperBlock));
memset((char *) &m_superBlock, 0, sizeof(SDRDaemonSuperBlock)); memset((char *) &m_superBlock, 0, sizeof(RemoteSuperBlock));
m_currentMetaFEC.init(); m_currentMetaFEC.init();
m_bufMeta = new uint8_t[m_udpSize]; m_bufMeta = new uint8_t[m_udpSize];
m_buf = new uint8_t[m_udpSize]; m_buf = new uint8_t[m_udpSize];
@ -75,7 +77,7 @@ void UDPSinkFEC::setTxDelay(float txDelayRatio)
// divided by sample rate gives the frame process time // divided by sample rate gives the frame process time
// divided by the number of actual blocks including FEC blocks gives the block (i.e. UDP block) process time // divided by the number of actual blocks including FEC blocks gives the block (i.e. UDP block) process time
m_txDelayRatio = txDelayRatio; m_txDelayRatio = txDelayRatio;
int samplesPerBlock = SDRDaemonNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); int samplesPerBlock = RemoteNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8);
double delay = ((127*samplesPerBlock*txDelayRatio) / m_sampleRate)/(128 + m_nbBlocksFEC); double delay = ((127*samplesPerBlock*txDelayRatio) / m_sampleRate)/(128 + m_nbBlocksFEC);
m_txDelay = delay * 1e6; m_txDelay = delay * 1e6;
qDebug() << "UDPSinkFEC::setTxDelay: txDelay: " << txDelayRatio << " m_txDelay: " << m_txDelay << " us"; qDebug() << "UDPSinkFEC::setTxDelay: txDelay: " << txDelayRatio << " m_txDelay: " << m_txDelay << " us";
@ -117,7 +119,7 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
if (m_txBlockIndex == 0) // Tx block index 0 is a block with only meta data if (m_txBlockIndex == 0) // Tx block index 0 is a block with only meta data
{ {
SDRDaemonMetaDataFEC metaData; RemoteMetaDataFEC metaData;
uint64_t ts_usecs = TimeUtil::nowus(); uint64_t ts_usecs = TimeUtil::nowus();
@ -142,9 +144,8 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
m_superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); m_superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ;
SDRDaemonMetaDataFEC *destMeta = (SDRDaemonMetaDataFEC *) &m_superBlock.m_protectedBlock; RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &m_superBlock.m_protectedBlock;
*destMeta = metaData; *destMeta = metaData;
//memcpy((char *) &m_superBlock.m_protectedBlock, (const char *) &metaData, sizeof(SDRDaemonMetaDataFEC));
if (!(metaData == m_currentMetaFEC)) if (!(metaData == m_currentMetaFEC))
{ {
@ -166,7 +167,7 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
m_txBlockIndex = 1; // next Tx block with data m_txBlockIndex = 1; // next Tx block with data
} }
int samplesPerBlock = SDRDaemonNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); // two I or Q samples int samplesPerBlock = RemoteNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); // two I or Q samples
if (m_sampleIndex + inRemainingSamples < samplesPerBlock) // there is still room in the current super block if (m_sampleIndex + inRemainingSamples < samplesPerBlock) // there is still room in the current super block
{ {

Wyświetl plik

@ -14,9 +14,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFEC_H_ #ifndef PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_
#define PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFEC_H_ #define PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_
#include <channel/remotedatablock.h>
#include <string.h> #include <string.h>
#include <cstddef> #include <cstddef>
@ -26,7 +27,6 @@
#include "dsp/dsptypes.h" #include "dsp/dsptypes.h"
#include "util/CRC64.h" #include "util/CRC64.h"
#include "channel/sdrdaemondatablock.h"
class UDPSinkFECWorker; class UDPSinkFECWorker;
@ -86,12 +86,12 @@ private:
uint8_t* m_bufMeta; uint8_t* m_bufMeta;
uint8_t* m_buf; uint8_t* m_buf;
SDRDaemonMetaDataFEC m_currentMetaFEC; //!< Meta data for current frame RemoteMetaDataFEC m_currentMetaFEC; //!< Meta data for current frame
uint32_t m_nbBlocksFEC; //!< Variable number of FEC blocks uint32_t m_nbBlocksFEC; //!< Variable number of FEC blocks
float m_txDelayRatio; //!< Delay in ratio of nominal frame period float m_txDelayRatio; //!< Delay in ratio of nominal frame period
uint32_t m_txDelay; //!< Delay in microseconds (usleep) between each sending of an UDP datagram uint32_t m_txDelay; //!< Delay in microseconds (usleep) between each sending of an UDP datagram
SDRDaemonSuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC RemoteSuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC
SDRDaemonSuperBlock m_superBlock; //!< current super block being built RemoteSuperBlock m_superBlock; //!< current super block being built
int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row
int m_txBlocksIndex; //!< Current index of Tx blocks row int m_txBlocksIndex; //!< Current index of Tx blocks row
uint16_t m_frameCount; //!< transmission frame count uint16_t m_frameCount; //!< transmission frame count
@ -102,4 +102,4 @@ private:
uint16_t m_remotePort; uint16_t m_remotePort;
}; };
#endif /* PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFEC_H_ */ #endif /* PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_ */

Wyświetl plik

@ -14,9 +14,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include "udpsinkfecworker.h"
#include <QUdpSocket> #include <QUdpSocket>
#include "udpsinkfecworker.h"
MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgUDPFECEncodeAndSend, Message) MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgUDPFECEncodeAndSend, Message)
MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgConfigureRemoteAddress, Message) MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgConfigureRemoteAddress, Message)
@ -81,7 +82,7 @@ void UDPSinkFECWorker::run()
qDebug("UDPSinkFECWorker::process: stopped"); qDebug("UDPSinkFECWorker::process: stopped");
} }
void UDPSinkFECWorker::pushTxFrame(SDRDaemonSuperBlock *txBlocks, void UDPSinkFECWorker::pushTxFrame(RemoteSuperBlock *txBlocks,
uint32_t nbBlocksFEC, uint32_t nbBlocksFEC,
uint32_t txDelay, uint32_t txDelay,
uint16_t frameIndex) uint16_t frameIndex)
@ -117,7 +118,7 @@ void UDPSinkFECWorker::handleInputMessages()
else if (MsgStartStop::match(*message)) else if (MsgStartStop::match(*message))
{ {
MsgStartStop* notif = (MsgStartStop*) message; MsgStartStop* notif = (MsgStartStop*) message;
qDebug("DaemonSinkThread::handleInputMessages: MsgStartStop: %s", notif->getStartStop() ? "start" : "stop"); qDebug("UDPSinkFECWorker::handleInputMessages: MsgStartStop: %s", notif->getStartStop() ? "start" : "stop");
if (notif->getStartStop()) { if (notif->getStartStop()) {
startWork(); startWork();
@ -130,28 +131,27 @@ void UDPSinkFECWorker::handleInputMessages()
} }
} }
void UDPSinkFECWorker::encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay) void UDPSinkFECWorker::encodeAndTransmit(RemoteSuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay)
{ {
CM256::cm256_encoder_params cm256Params; //!< Main interface with CM256 encoder CM256::cm256_encoder_params cm256Params; //!< Main interface with CM256 encoder
CM256::cm256_block descriptorBlocks[256]; //!< Pointers to data for CM256 encoder CM256::cm256_block descriptorBlocks[256]; //!< Pointers to data for CM256 encoder
SDRDaemonProtectedBlock fecBlocks[256]; //!< FEC data RemoteProtectedBlock fecBlocks[256]; //!< FEC data
if ((nbBlocksFEC == 0) || !m_cm256Valid) if ((nbBlocksFEC == 0) || !m_cm256Valid)
{ {
if (m_udpSocket) if (m_udpSocket)
{ {
for (unsigned int i = 0; i < SDRDaemonNbOrginalBlocks; i++) for (unsigned int i = 0; i < RemoteNbOrginalBlocks; i++)
{ {
//m_socket.SendDataGram((const void *) &txBlockx[i], SDRDaemonUdpSize, m_remoteAddress.toStdString(), (uint32_t) m_remotePort); m_udpSocket->writeDatagram((const char *) &txBlockx[i], RemoteUdpSize, m_remoteHostAddress, m_remotePort);
m_udpSocket->writeDatagram((const char *) &txBlockx[i], SDRDaemonUdpSize, m_remoteHostAddress, m_remotePort);
usleep(txDelay); usleep(txDelay);
} }
} }
} }
else else
{ {
cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock); cm256Params.BlockBytes = sizeof(RemoteProtectedBlock);
cm256Params.OriginalCount = SDRDaemonNbOrginalBlocks; cm256Params.OriginalCount = RemoteNbOrginalBlocks;
cm256Params.RecoveryCount = nbBlocksFEC; cm256Params.RecoveryCount = nbBlocksFEC;
@ -159,7 +159,7 @@ void UDPSinkFECWorker::encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i) for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i)
{ {
if (i >= cm256Params.OriginalCount) { if (i >= cm256Params.OriginalCount) {
memset((char *) &txBlockx[i].m_protectedBlock, 0, sizeof(SDRDaemonProtectedBlock)); memset((char *) &txBlockx[i].m_protectedBlock, 0, sizeof(RemoteProtectedBlock));
} }
txBlockx[i].m_header.m_frameIndex = frameIndex; txBlockx[i].m_header.m_frameIndex = frameIndex;
@ -188,13 +188,13 @@ void UDPSinkFECWorker::encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t
{ {
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++) for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
{ {
#ifdef SDRDAEMON_PUNCTURE #ifdef REMOTE_PUNCTURE
if (i == SDRDAEMON_PUNCTURE) { if (i == REMOTE_PUNCTURE) {
continue; continue;
} }
#endif #endif
m_udpSocket->writeDatagram((const char *) &txBlockx[i], SDRDaemonUdpSize, m_remoteHostAddress, m_remotePort); m_udpSocket->writeDatagram((const char *) &txBlockx[i], RemoteUdpSize, m_remoteHostAddress, m_remotePort);
usleep(txDelay); usleep(txDelay);
} }
} }

Wyświetl plik

@ -14,9 +14,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFECWORKER_H_ #ifndef PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFECWORKER_H_
#define PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFECWORKER_H_ #define PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFECWORKER_H_
#include <channel/remotedatablock.h>
#include <QThread> #include <QThread>
#include <QMutex> #include <QMutex>
#include <QWaitCondition> #include <QWaitCondition>
@ -26,7 +27,6 @@
#include "util/messagequeue.h" #include "util/messagequeue.h"
#include "util/message.h" #include "util/message.h"
#include "channel/sdrdaemondatablock.h"
class QUdpSocket; class QUdpSocket;
@ -38,13 +38,13 @@ public:
{ {
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
public: public:
SDRDaemonSuperBlock *getTxBlocks() const { return m_txBlockx; } RemoteSuperBlock *getTxBlocks() const { return m_txBlockx; }
uint32_t getNbBlocsFEC() const { return m_nbBlocksFEC; } uint32_t getNbBlocsFEC() const { return m_nbBlocksFEC; }
uint32_t getTxDelay() const { return m_txDelay; } uint32_t getTxDelay() const { return m_txDelay; }
uint16_t getFrameIndex() const { return m_frameIndex; } uint16_t getFrameIndex() const { return m_frameIndex; }
static MsgUDPFECEncodeAndSend* create( static MsgUDPFECEncodeAndSend* create(
SDRDaemonSuperBlock *txBlocks, RemoteSuperBlock *txBlocks,
uint32_t nbBlocksFEC, uint32_t nbBlocksFEC,
uint32_t txDelay, uint32_t txDelay,
uint16_t frameIndex) uint16_t frameIndex)
@ -53,13 +53,13 @@ public:
} }
private: private:
SDRDaemonSuperBlock *m_txBlockx; RemoteSuperBlock *m_txBlockx;
uint32_t m_nbBlocksFEC; uint32_t m_nbBlocksFEC;
uint32_t m_txDelay; uint32_t m_txDelay;
uint16_t m_frameIndex; uint16_t m_frameIndex;
MsgUDPFECEncodeAndSend( MsgUDPFECEncodeAndSend(
SDRDaemonSuperBlock *txBlocks, RemoteSuperBlock *txBlocks,
uint32_t nbBlocksFEC, uint32_t nbBlocksFEC,
uint32_t txDelay, uint32_t txDelay,
uint16_t frameIndex) : uint16_t frameIndex) :
@ -116,7 +116,7 @@ public:
void startStop(bool start); void startStop(bool start);
void pushTxFrame(SDRDaemonSuperBlock *txBlocks, void pushTxFrame(RemoteSuperBlock *txBlocks,
uint32_t nbBlocksFEC, uint32_t nbBlocksFEC,
uint32_t txDelay, uint32_t txDelay,
uint16_t frameIndex); uint16_t frameIndex);
@ -131,7 +131,7 @@ private:
void startWork(); void startWork();
void stopWork(); void stopWork();
void run(); void run();
void encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay); void encodeAndTransmit(RemoteSuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay);
QMutex m_startWaitMutex; QMutex m_startWaitMutex;
QWaitCondition m_startWaiter; QWaitCondition m_startWaiter;
@ -144,4 +144,4 @@ private:
QHostAddress m_remoteHostAddress; QHostAddress m_remoteHostAddress;
}; };
#endif /* PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFECWORKER_H_ */ #endif /* PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFECWORKER_H_ */

Wyświetl plik

@ -1,87 +0,0 @@
project(sdrdaemonsink)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if (HAS_SSSE3)
message(STATUS "SDRdaemonFEC: use SSSE3 SIMD" )
elseif (HAS_NEON)
message(STATUS "SDRdaemonFEC: use Neon SIMD" )
else()
message(STATUS "SDRdaemonFEC: Unsupported architecture")
return()
endif()
set(sdrdaemonsink_SOURCES
sdrdaemonsinkgui.cpp
sdrdaemonsinkoutput.cpp
sdrdaemonsinkplugin.cpp
sdrdaemonsinksettings.cpp
sdrdaemonsinkthread.cpp
udpsinkfec.cpp
udpsinkfecworker.cpp
)
set(sdrdaemonsink_HEADERS
sdrdaemonsinkgui.h
sdrdaemonsinkoutput.h
sdrdaemonsinkplugin.h
sdrdaemonsinksettings.h
sdrdaemonsinkthread.h
udpsinkfec.h
udpsinkfecworker.h
)
set(sdrdaemonsink_FORMS
sdrdaemonsinkgui.ui
)
if (BUILD_DEBIAN)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${LIBCM256CCSRC}
)
else (BUILD_DEBIAN)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${CMAKE_SOURCE_DIR}/devices
${CM256CC_INCLUDE_DIR}
)
endif (BUILD_DEBIAN)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
qt5_wrap_ui(sdrdaemonsink_FORMS_HEADERS ${sdrdaemonsink_FORMS})
add_library(outputsdrdaemonsink SHARED
${sdrdaemonsink_SOURCES}
${sdrdaemonsink_HEADERS_MOC}
${sdrdaemonsink_FORMS_HEADERS}
)
if (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsink
${QT_LIBRARIES}
sdrbase
sdrgui
swagger
cm256cc
)
else (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsink
${QT_LIBRARIES}
sdrbase
sdrgui
swagger
${CM256CC_LIBRARIES}
)
endif (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsink Qt5::Core Qt5::Widgets)
install(TARGETS outputsdrdaemonsink DESTINATION lib/plugins/samplesink)

Wyświetl plik

@ -50,8 +50,8 @@ SDRdaemonSourceBuffer::SDRdaemonSourceBuffer() :
m_tvOut_sec = 0; m_tvOut_sec = 0;
m_tvOut_usec = 0; m_tvOut_usec = 0;
m_readNbBytes = 1; m_readNbBytes = 1;
m_paramsCM256.BlockBytes = sizeof(SDRDaemonProtectedBlock); // never changes m_paramsCM256.BlockBytes = sizeof(RemoteProtectedBlock); // never changes
m_paramsCM256.OriginalCount = SDRDaemonNbOrginalBlocks; // never changes m_paramsCM256.OriginalCount = RemoteNbOrginalBlocks; // never changes
if (!m_cm256.isInitialized()) { if (!m_cm256.isInitialized()) {
m_cm256_OK = false; m_cm256_OK = false;
@ -81,7 +81,7 @@ void SDRdaemonSourceBuffer::initDecodeAllSlots()
m_decoderSlots[i].m_decoded = false; m_decoderSlots[i].m_decoded = false;
m_decoderSlots[i].m_metaRetrieved = false; m_decoderSlots[i].m_metaRetrieved = false;
resetOriginalBlocks(i); resetOriginalBlocks(i);
memset((void *) m_decoderSlots[i].m_recoveryBlocks, 0, SDRDaemonNbOrginalBlocks * sizeof(SDRDaemonProtectedBlock)); memset((void *) m_decoderSlots[i].m_recoveryBlocks, 0, RemoteNbOrginalBlocks * sizeof(RemoteProtectedBlock));
} }
} }
@ -118,7 +118,7 @@ void SDRdaemonSourceBuffer::initDecodeSlot(int slotIndex)
m_decoderSlots[slotIndex].m_metaRetrieved = false; m_decoderSlots[slotIndex].m_metaRetrieved = false;
resetOriginalBlocks(slotIndex); resetOriginalBlocks(slotIndex);
memset((void *) m_decoderSlots[slotIndex].m_recoveryBlocks, 0, SDRDaemonNbOrginalBlocks * sizeof(SDRDaemonProtectedBlock)); memset((void *) m_decoderSlots[slotIndex].m_recoveryBlocks, 0, RemoteNbOrginalBlocks * sizeof(RemoteProtectedBlock));
} }
void SDRdaemonSourceBuffer::initReadIndex() void SDRdaemonSourceBuffer::initReadIndex()
@ -190,7 +190,7 @@ void SDRdaemonSourceBuffer::checkSlotData(int slotIndex)
void SDRdaemonSourceBuffer::writeData(char *array) void SDRdaemonSourceBuffer::writeData(char *array)
{ {
SDRDaemonSuperBlock *superBlock = (SDRDaemonSuperBlock *) array; RemoteSuperBlock *superBlock = (RemoteSuperBlock *) array;
int frameIndex = superBlock->m_header.m_frameIndex; int frameIndex = superBlock->m_header.m_frameIndex;
int decoderIndex = frameIndex % nbDecoderSlots; int decoderIndex = frameIndex % nbDecoderSlots;
@ -214,7 +214,7 @@ void SDRdaemonSourceBuffer::writeData(char *array)
// Block processing // Block processing
if (m_decoderSlots[decoderIndex].m_blockCount < SDRDaemonNbOrginalBlocks) // not enough blocks to decode -> store data if (m_decoderSlots[decoderIndex].m_blockCount < RemoteNbOrginalBlocks) // not enough blocks to decode -> store data
{ {
int blockIndex = superBlock->m_header.m_blockIndex; int blockIndex = superBlock->m_header.m_blockIndex;
int blockCount = m_decoderSlots[decoderIndex].m_blockCount; int blockCount = m_decoderSlots[decoderIndex].m_blockCount;
@ -226,7 +226,7 @@ void SDRdaemonSourceBuffer::writeData(char *array)
m_decoderSlots[decoderIndex].m_metaRetrieved = true; m_decoderSlots[decoderIndex].m_metaRetrieved = true;
} }
if (blockIndex < SDRDaemonNbOrginalBlocks) // original data if (blockIndex < RemoteNbOrginalBlocks) // original data
{ {
m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[blockCount].Block = (void *) storeOriginalBlock(decoderIndex, blockIndex, superBlock->m_protectedBlock); m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[blockCount].Block = (void *) storeOriginalBlock(decoderIndex, blockIndex, superBlock->m_protectedBlock);
m_decoderSlots[decoderIndex].m_originalCount++; m_decoderSlots[decoderIndex].m_originalCount++;
@ -241,14 +241,14 @@ void SDRdaemonSourceBuffer::writeData(char *array)
m_decoderSlots[decoderIndex].m_blockCount++; m_decoderSlots[decoderIndex].m_blockCount++;
if (m_decoderSlots[decoderIndex].m_blockCount == SDRDaemonNbOrginalBlocks) // ready to decode if (m_decoderSlots[decoderIndex].m_blockCount == RemoteNbOrginalBlocks) // ready to decode
{ {
m_decoderSlots[decoderIndex].m_decoded = true; m_decoderSlots[decoderIndex].m_decoded = true;
if (m_cm256_OK && (m_decoderSlots[decoderIndex].m_recoveryCount > 0)) // recovery data used => need to decode FEC if (m_cm256_OK && (m_decoderSlots[decoderIndex].m_recoveryCount > 0)) // recovery data used => need to decode FEC
{ {
m_paramsCM256.BlockBytes = sizeof(SDRDaemonProtectedBlock); // never changes m_paramsCM256.BlockBytes = sizeof(RemoteProtectedBlock); // never changes
m_paramsCM256.OriginalCount = SDRDaemonNbOrginalBlocks; // never changes m_paramsCM256.OriginalCount = RemoteNbOrginalBlocks; // never changes
if (m_decoderSlots[decoderIndex].m_metaRetrieved) { if (m_decoderSlots[decoderIndex].m_metaRetrieved) {
m_paramsCM256.RecoveryCount = m_currentMeta.m_nbFECBlocks; m_paramsCM256.RecoveryCount = m_currentMeta.m_nbFECBlocks;
@ -274,13 +274,13 @@ void SDRdaemonSourceBuffer::writeData(char *array)
for (int ir = 0; ir < m_decoderSlots[decoderIndex].m_recoveryCount; ir++) // restore missing blocks for (int ir = 0; ir < m_decoderSlots[decoderIndex].m_recoveryCount; ir++) // restore missing blocks
{ {
int recoveryIndex = SDRDaemonNbOrginalBlocks - m_decoderSlots[decoderIndex].m_recoveryCount + ir; int recoveryIndex = RemoteNbOrginalBlocks - m_decoderSlots[decoderIndex].m_recoveryCount + ir;
int blockIndex = m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[recoveryIndex].Index; int blockIndex = m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[recoveryIndex].Index;
SDRDaemonProtectedBlock *recoveredBlock = (SDRDaemonProtectedBlock *) m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[recoveryIndex].Block; RemoteProtectedBlock *recoveredBlock = (RemoteProtectedBlock *) m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[recoveryIndex].Block;
if (blockIndex == 0) // first block with meta if (blockIndex == 0) // first block with meta
{ {
SDRDaemonMetaDataFEC *metaData = (SDRDaemonMetaDataFEC *) recoveredBlock; RemoteMetaDataFEC *metaData = (RemoteMetaDataFEC *) recoveredBlock;
boost::crc_32_type crc32; boost::crc_32_type crc32;
crc32.process_bytes(metaData, 20); crc32.process_bytes(metaData, 20);
@ -305,7 +305,7 @@ void SDRdaemonSourceBuffer::writeData(char *array)
if (m_decoderSlots[decoderIndex].m_metaRetrieved) // block zero with its meta data has been received if (m_decoderSlots[decoderIndex].m_metaRetrieved) // block zero with its meta data has been received
{ {
SDRDaemonMetaDataFEC *metaData = getMetaData(decoderIndex); RemoteMetaDataFEC *metaData = getMetaData(decoderIndex);
if (!(*metaData == m_currentMeta)) if (!(*metaData == m_currentMeta))
{ {
@ -368,7 +368,7 @@ uint8_t *SDRdaemonSourceBuffer::readData(int32_t length)
} }
} }
void SDRdaemonSourceBuffer::printMeta(const QString& header, SDRDaemonMetaDataFEC *metaData) void SDRdaemonSourceBuffer::printMeta(const QString& header, RemoteMetaDataFEC *metaData)
{ {
qDebug() << header << ": " qDebug() << header << ": "
<< "|" << metaData->m_centerFrequency << "|" << metaData->m_centerFrequency

Wyświetl plik

@ -17,12 +17,12 @@
#ifndef PLUGINS_SAMPLESOURCE_SDRDAEMONSOURCE_SDRDAEMONSOURCEBUFFER_H_ #ifndef PLUGINS_SAMPLESOURCE_SDRDAEMONSOURCE_SDRDAEMONSOURCEBUFFER_H_
#define PLUGINS_SAMPLESOURCE_SDRDAEMONSOURCE_SDRDAEMONSOURCEBUFFER_H_ #define PLUGINS_SAMPLESOURCE_SDRDAEMONSOURCE_SDRDAEMONSOURCEBUFFER_H_
#include <channel/remotedatablock.h>
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <cstdlib> #include <cstdlib>
#include "cm256.h" #include "cm256.h"
#include "util/movingaverage.h" #include "util/movingaverage.h"
#include "channel/sdrdaemondatablock.h"
#define SDRDAEMONSOURCE_UDPSIZE 512 // UDP payload size #define SDRDAEMONSOURCE_UDPSIZE 512 // UDP payload size
@ -40,7 +40,7 @@ public:
uint8_t *readData(int32_t length); //!< Read data from buffer uint8_t *readData(int32_t length); //!< Read data from buffer
// meta data // meta data
const SDRDaemonMetaDataFEC& getCurrentMeta() const { return m_currentMeta; } const RemoteMetaDataFEC& getCurrentMeta() const { return m_currentMeta; }
// samples timestamp // samples timestamp
uint32_t getTVOutSec() const { return m_tvOut_sec; } uint32_t getTVOutSec() const { return m_tvOut_sec; }
@ -105,7 +105,7 @@ public:
} }
} }
static const int framesSize = SDRDAEMONSOURCE_NBDECODERSLOTS * (SDRDaemonNbOrginalBlocks - 1) * SDRDaemonNbBytesPerBlock; static const int framesSize = SDRDAEMONSOURCE_NBDECODERSLOTS * (RemoteNbOrginalBlocks - 1) * RemoteNbBytesPerBlock;
private: private:
static const int nbDecoderSlots = SDRDAEMONSOURCE_NBDECODERSLOTS; static const int nbDecoderSlots = SDRDAEMONSOURCE_NBDECODERSLOTS;
@ -113,16 +113,16 @@ private:
#pragma pack(push, 1) #pragma pack(push, 1)
struct BufferFrame struct BufferFrame
{ {
SDRDaemonProtectedBlock m_blocks[SDRDaemonNbOrginalBlocks - 1]; RemoteProtectedBlock m_blocks[RemoteNbOrginalBlocks - 1];
}; };
#pragma pack(pop) #pragma pack(pop)
struct DecoderSlot struct DecoderSlot
{ {
SDRDaemonProtectedBlock m_blockZero; //!< First block of a frame. Has meta data. RemoteProtectedBlock m_blockZero; //!< First block of a frame. Has meta data.
SDRDaemonProtectedBlock m_originalBlocks[SDRDaemonNbOrginalBlocks]; //!< Original blocks retrieved directly or by later FEC RemoteProtectedBlock m_originalBlocks[RemoteNbOrginalBlocks]; //!< Original blocks retrieved directly or by later FEC
SDRDaemonProtectedBlock m_recoveryBlocks[SDRDaemonNbOrginalBlocks]; //!< Recovery blocks (FEC blocks) with max size RemoteProtectedBlock m_recoveryBlocks[RemoteNbOrginalBlocks]; //!< Recovery blocks (FEC blocks) with max size
CM256::cm256_block m_cm256DescriptorBlocks[SDRDaemonNbOrginalBlocks]; //!< CM256 decoder descriptors (block addresses and block indexes) CM256::cm256_block m_cm256DescriptorBlocks[RemoteNbOrginalBlocks]; //!< CM256 decoder descriptors (block addresses and block indexes)
int m_blockCount; //!< number of blocks received for this frame int m_blockCount; //!< number of blocks received for this frame
int m_originalCount; //!< number of original blocks received int m_originalCount; //!< number of original blocks received
int m_recoveryCount; //!< number of recovery blocks received int m_recoveryCount; //!< number of recovery blocks received
@ -130,7 +130,7 @@ private:
bool m_metaRetrieved; //!< true if meta data (block zero) was retrieved bool m_metaRetrieved; //!< true if meta data (block zero) was retrieved
}; };
SDRDaemonMetaDataFEC m_currentMeta; //!< Stored current meta data RemoteMetaDataFEC m_currentMeta; //!< Stored current meta data
CM256::cm256_encoder_params m_paramsCM256; //!< CM256 decoder parameters block CM256::cm256_encoder_params m_paramsCM256; //!< CM256 decoder parameters block
DecoderSlot m_decoderSlots[nbDecoderSlots]; //!< CM256 decoding control/buffer slots DecoderSlot m_decoderSlots[nbDecoderSlots]; //!< CM256 decoding control/buffer slots
BufferFrame m_frames[nbDecoderSlots]; //!< Samples buffer BufferFrame m_frames[nbDecoderSlots]; //!< Samples buffer
@ -165,7 +165,7 @@ private:
CM256 m_cm256; //!< CM256 library CM256 m_cm256; //!< CM256 library
bool m_cm256_OK; //!< CM256 library initialized OK bool m_cm256_OK; //!< CM256 library initialized OK
inline SDRDaemonProtectedBlock* storeOriginalBlock(int slotIndex, int blockIndex, const SDRDaemonProtectedBlock& protectedBlock) inline RemoteProtectedBlock* storeOriginalBlock(int slotIndex, int blockIndex, const RemoteProtectedBlock& protectedBlock)
{ {
if (blockIndex == 0) { if (blockIndex == 0) {
// m_decoderSlots[slotIndex].m_originalBlocks[0] = protectedBlock; // m_decoderSlots[slotIndex].m_originalBlocks[0] = protectedBlock;
@ -180,7 +180,7 @@ private:
} }
} }
inline SDRDaemonProtectedBlock& getOriginalBlock(int slotIndex, int blockIndex) inline RemoteProtectedBlock& getOriginalBlock(int slotIndex, int blockIndex)
{ {
if (blockIndex == 0) { if (blockIndex == 0) {
// return m_decoderSlots[slotIndex].m_originalBlocks[0]; // return m_decoderSlots[slotIndex].m_originalBlocks[0];
@ -191,17 +191,17 @@ private:
} }
} }
inline SDRDaemonMetaDataFEC *getMetaData(int slotIndex) inline RemoteMetaDataFEC *getMetaData(int slotIndex)
{ {
// return (MetaDataFEC *) &m_decoderSlots[slotIndex].m_originalBlocks[0]; // return (MetaDataFEC *) &m_decoderSlots[slotIndex].m_originalBlocks[0];
return (SDRDaemonMetaDataFEC *) &m_decoderSlots[slotIndex].m_blockZero; return (RemoteMetaDataFEC *) &m_decoderSlots[slotIndex].m_blockZero;
} }
inline void resetOriginalBlocks(int slotIndex) inline void resetOriginalBlocks(int slotIndex)
{ {
// memset((void *) m_decoderSlots[slotIndex].m_originalBlocks, 0, m_nbOriginalBlocks * sizeof(ProtectedBlock)); // memset((void *) m_decoderSlots[slotIndex].m_originalBlocks, 0, m_nbOriginalBlocks * sizeof(ProtectedBlock));
memset((void *) &m_decoderSlots[slotIndex].m_blockZero, 0, sizeof(SDRDaemonProtectedBlock)); memset((void *) &m_decoderSlots[slotIndex].m_blockZero, 0, sizeof(RemoteProtectedBlock));
memset((void *) m_frames[slotIndex].m_blocks, 0, (SDRDaemonNbOrginalBlocks - 1) * sizeof(SDRDaemonProtectedBlock)); memset((void *) m_frames[slotIndex].m_blocks, 0, (RemoteNbOrginalBlocks - 1) * sizeof(RemoteProtectedBlock));
} }
void initDecodeAllSlots(); void initDecodeAllSlots();
@ -210,7 +210,7 @@ private:
void checkSlotData(int slotIndex); void checkSlotData(int slotIndex);
void initDecodeSlot(int slotIndex); void initDecodeSlot(int slotIndex);
static void printMeta(const QString& header, SDRDaemonMetaDataFEC *metaData); static void printMeta(const QString& header, RemoteMetaDataFEC *metaData);
}; };

Wyświetl plik

@ -54,7 +54,7 @@ SDRdaemonSourceUDPHandler::SDRdaemonSourceUDPHandler(SampleSinkFifo *sampleFifo,
m_throttleToggle(false), m_throttleToggle(false),
m_autoCorrBuffer(true) m_autoCorrBuffer(true)
{ {
m_udpBuf = new char[SDRDaemonUdpSize]; m_udpBuf = new char[RemoteUdpSize];
#ifdef USE_INTERNAL_TIMER #ifdef USE_INTERNAL_TIMER
#warning "Uses internal timer" #warning "Uses internal timer"
@ -165,7 +165,7 @@ void SDRdaemonSourceUDPHandler::dataReadyRead()
qint64 pendingDataSize = m_dataSocket->pendingDatagramSize(); qint64 pendingDataSize = m_dataSocket->pendingDatagramSize();
m_udpReadBytes += m_dataSocket->readDatagram(&m_udpBuf[m_udpReadBytes], pendingDataSize, &m_remoteAddress, 0); m_udpReadBytes += m_dataSocket->readDatagram(&m_udpBuf[m_udpReadBytes], pendingDataSize, &m_remoteAddress, 0);
if (m_udpReadBytes == SDRDaemonUdpSize) { if (m_udpReadBytes == RemoteUdpSize) {
processData(); processData();
m_udpReadBytes = 0; m_udpReadBytes = 0;
} }
@ -175,7 +175,7 @@ void SDRdaemonSourceUDPHandler::dataReadyRead()
void SDRdaemonSourceUDPHandler::processData() void SDRdaemonSourceUDPHandler::processData()
{ {
m_sdrDaemonBuffer.writeData(m_udpBuf); m_sdrDaemonBuffer.writeData(m_udpBuf);
const SDRDaemonMetaDataFEC& metaData = m_sdrDaemonBuffer.getCurrentMeta(); const RemoteMetaDataFEC& metaData = m_sdrDaemonBuffer.getCurrentMeta();
bool change = false; bool change = false;
m_tv_msec = m_sdrDaemonBuffer.getTVOutMSec(); m_tv_msec = m_sdrDaemonBuffer.getTVOutMSec();
@ -259,7 +259,7 @@ void SDRdaemonSourceUDPHandler::tick()
m_readLengthSamples += m_sdrDaemonBuffer.getRWBalanceCorrection(); m_readLengthSamples += m_sdrDaemonBuffer.getRWBalanceCorrection();
} }
const SDRDaemonMetaDataFEC& metaData = m_sdrDaemonBuffer.getCurrentMeta(); const RemoteMetaDataFEC& metaData = m_sdrDaemonBuffer.getCurrentMeta();
m_readLength = m_readLengthSamples * (metaData.m_sampleBytes & 0xF) * 2; m_readLength = m_readLengthSamples * (metaData.m_sampleBytes & 0xF) * 2;
if ((metaData.m_sampleBits == 16) && (SDR_RX_SAMP_SZ == 24)) // 16 -> 24 bits if ((metaData.m_sampleBits == 16) && (SDR_RX_SAMP_SZ == 24)) // 16 -> 24 bits

Wyświetl plik

@ -43,7 +43,7 @@ public:
void stop(); void stop();
void configureUDPLink(const QString& address, quint16 port); void configureUDPLink(const QString& address, quint16 port);
void getRemoteAddress(QString& s) const { s = m_remoteAddress.toString(); } void getRemoteAddress(QString& s) const { s = m_remoteAddress.toString(); }
int getNbOriginalBlocks() const { return SDRDaemonNbOrginalBlocks; } int getNbOriginalBlocks() const { return RemoteNbOrginalBlocks; }
bool isStreaming() const { return m_masterTimerConnected; } bool isStreaming() const { return m_masterTimerConnected; }
int getSampleRate() const { return m_samplerate; } int getSampleRate() const { return m_samplerate; }
int getCenterFrequency() const { return m_centerFrequency * 1000; } int getCenterFrequency() const { return m_centerFrequency * 1000; }

Wyświetl plik

@ -25,7 +25,7 @@ endif(LIBUSB_FOUND AND LIBIIO_FOUND)
find_package(CM256cc) find_package(CM256cc)
if(CM256CC_FOUND) if(CM256CC_FOUND)
add_subdirectory(sdrdaemonsink) add_subdirectory(remoteoutput)
endif(CM256CC_FOUND) endif(CM256CC_FOUND)
find_package(SoapySDR) find_package(SoapySDR)
@ -44,7 +44,7 @@ if (BUILD_DEBIAN)
add_subdirectory(hackrfoutput) add_subdirectory(hackrfoutput)
add_subdirectory(limesdroutput) add_subdirectory(limesdroutput)
add_subdirectory(plutosdroutput) add_subdirectory(plutosdroutput)
add_subdirectory(sdrdaemonsink) add_subdirectory(remoteoutput)
endif (BUILD_DEBIAN) endif (BUILD_DEBIAN)
add_subdirectory(filesink) add_subdirectory(filesink)

Wyświetl plik

@ -1,7 +1,7 @@
project(sdrdaemonsink) project(remoteoutput)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PLUGIN_PREFIX "../../../plugins/samplesink/sdrdaemonsink") set(PLUGIN_PREFIX "../../../plugins/samplesink/remoteoutput")
if (HAS_SSSE3) if (HAS_SSSE3)
message(STATUS "SDRdaemonFEC: use SSSE3 SIMD" ) message(STATUS "SDRdaemonFEC: use SSSE3 SIMD" )
@ -12,20 +12,20 @@ else()
return() return()
endif() endif()
set(sdrdaemonsink_SOURCES set(remoteoutput_SOURCES
${PLUGIN_PREFIX}/sdrdaemonsinkoutput.cpp ${PLUGIN_PREFIX}/remoteoutput.cpp
${PLUGIN_PREFIX}/sdrdaemonsinkplugin.cpp ${PLUGIN_PREFIX}/remoteoutputplugin.cpp
${PLUGIN_PREFIX}/sdrdaemonsinksettings.cpp ${PLUGIN_PREFIX}/remoteoutputsettings.cpp
${PLUGIN_PREFIX}/sdrdaemonsinkthread.cpp ${PLUGIN_PREFIX}/remoteoutputthread.cpp
${PLUGIN_PREFIX}/udpsinkfec.cpp ${PLUGIN_PREFIX}/udpsinkfec.cpp
${PLUGIN_PREFIX}/udpsinkfecworker.cpp ${PLUGIN_PREFIX}/udpsinkfecworker.cpp
) )
set(sdrdaemonsink_HEADERS set(remoteoutput_HEADERS
${PLUGIN_PREFIX}/sdrdaemonsinkoutput.h ${PLUGIN_PREFIX}/remoteoutput.h
${PLUGIN_PREFIX}/sdrdaemonsinkplugin.h ${PLUGIN_PREFIX}/remoteoutputplugin.h
${PLUGIN_PREFIX}/sdrdaemonsinksettings.h ${PLUGIN_PREFIX}/remoteoutputsettings.h
${PLUGIN_PREFIX}/sdrdaemonsinkthread.h ${PLUGIN_PREFIX}/remoteoutputthread.h
${PLUGIN_PREFIX}/udpsinkfec.h ${PLUGIN_PREFIX}/udpsinkfec.h
${PLUGIN_PREFIX}/udpsinkfecworker.h ${PLUGIN_PREFIX}/udpsinkfecworker.h
) )
@ -51,20 +51,20 @@ add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN) add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED) add_definitions(-DQT_SHARED)
add_library(outputsdrdaemonsinksrv SHARED add_library(outputremotesrv SHARED
${sdrdaemonsink_SOURCES} ${remoteoutput_SOURCES}
${sdrdaemonsink_HEADERS_MOC} ${remoteoutput_HEADERS_MOC}
) )
if (BUILD_DEBIAN) if (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsinksrv target_link_libraries(outputremotesrv
${QT_LIBRARIES} ${QT_LIBRARIES}
sdrbase sdrbase
swagger swagger
cm256cc cm256cc
) )
else (BUILD_DEBIAN) else (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsinksrv target_link_libraries(outputremotesrv
${QT_LIBRARIES} ${QT_LIBRARIES}
sdrbase sdrbase
swagger swagger
@ -72,6 +72,6 @@ target_link_libraries(outputsdrdaemonsinksrv
) )
endif (BUILD_DEBIAN) endif (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsinksrv Qt5::Core) target_link_libraries(outputremotesrv Qt5::Core)
install(TARGETS outputsdrdaemonsinksrv DESTINATION lib/pluginssrv/samplesink) install(TARGETS outputremotesrv DESTINATION lib/pluginssrv/samplesink)

Wyświetl plik

@ -13,8 +13,8 @@ set(sdrbase_SOURCES
channel/channelsinkapi.cpp channel/channelsinkapi.cpp
channel/channelsourceapi.cpp channel/channelsourceapi.cpp
channel/sdrdaemondataqueue.cpp channel/remotedataqueue.cpp
channel/sdrdaemondatareadqueue.cpp channel/remotedatareadqueue.cpp
commands/command.cpp commands/command.cpp
@ -105,9 +105,9 @@ set(sdrbase_HEADERS
channel/channelsinkapi.h channel/channelsinkapi.h
channel/channelsourceapi.h channel/channelsourceapi.h
channel/sdrdaemondataqueue.h channel/remotedataqueue.h
channel/sdrdaemondatareadqueue.h channel/remotedatareadqueue.h
channel/sdrdaemondatablock.h channel/remotedatablock.h
commands/command.h commands/command.h

Wyświetl plik

@ -1,11 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB. // // Copyright (C) 2018 Edouard Griffiths, F4EXB. //
// // // //
// SDRdaemon sink channel (Rx) data block // // Remote sink channel (Rx) data block //
// // // //
// SDRdaemon is a detached SDR front end that handles the interface with a // // SDRangel can serve as a remote SDR front end that handles the interface //
// physical device and sends or receives the I/Q samples stream to or from a // // with a physical device and sends or receives the I/Q samples stream via UDP //
// SDRangel instance via UDP. It is controlled via a Web REST API. // // to or from another SDRangel instance or any program implementing the same //
// protocol. The remote SDRangel is controlled via its Web REST API. //
// // // //
// This program is free software; you can redistribute it and/or modify // // 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 // // it under the terms of the GNU General Public License as published by //
@ -34,7 +35,7 @@
//#define UDPSINKFEC_NBTXBLOCKS 8 //#define UDPSINKFEC_NBTXBLOCKS 8
#pragma pack(push, 1) #pragma pack(push, 1)
struct SDRDaemonMetaDataFEC struct RemoteMetaDataFEC
{ {
uint32_t m_centerFrequency; //!< 4 center frequency in kHz uint32_t m_centerFrequency; //!< 4 center frequency in kHz
uint32_t m_sampleRate; //!< 8 sample rate in Hz uint32_t m_sampleRate; //!< 8 sample rate in Hz
@ -47,7 +48,7 @@ struct SDRDaemonMetaDataFEC
uint32_t m_tv_usec; //!< 20 microseconds of timestamp at start time of super-frame processing uint32_t m_tv_usec; //!< 20 microseconds of timestamp at start time of super-frame processing
uint32_t m_crc32; //!< 24 CRC32 of the above uint32_t m_crc32; //!< 24 CRC32 of the above
bool operator==(const SDRDaemonMetaDataFEC& rhs) bool operator==(const RemoteMetaDataFEC& rhs)
{ {
// Only the first 6 fields are relevant // Only the first 6 fields are relevant
return (m_centerFrequency == rhs.m_centerFrequency) return (m_centerFrequency == rhs.m_centerFrequency)
@ -72,7 +73,7 @@ struct SDRDaemonMetaDataFEC
} }
}; };
struct SDRDaemonHeader struct RemoteHeader
{ {
uint16_t m_frameIndex; uint16_t m_frameIndex;
uint8_t m_blockIndex; uint8_t m_blockIndex;
@ -92,23 +93,23 @@ struct SDRDaemonHeader
} }
}; };
static const int SDRDaemonUdpSize = UDPSINKFEC_UDPSIZE; static const int RemoteUdpSize = UDPSINKFEC_UDPSIZE;
static const int SDRDaemonNbOrginalBlocks = UDPSINKFEC_NBORIGINALBLOCKS; static const int RemoteNbOrginalBlocks = UDPSINKFEC_NBORIGINALBLOCKS;
static const int SDRDaemonNbBytesPerBlock = UDPSINKFEC_UDPSIZE - sizeof(SDRDaemonHeader); static const int RemoteNbBytesPerBlock = UDPSINKFEC_UDPSIZE - sizeof(RemoteHeader);
struct SDRDaemonProtectedBlock struct RemoteProtectedBlock
{ {
uint8_t buf[SDRDaemonNbBytesPerBlock]; uint8_t buf[RemoteNbBytesPerBlock];
void init() { void init() {
std::fill(buf, buf+SDRDaemonNbBytesPerBlock, 0); std::fill(buf, buf+RemoteNbBytesPerBlock, 0);
} }
}; };
struct SDRDaemonSuperBlock struct RemoteSuperBlock
{ {
SDRDaemonHeader m_header; RemoteHeader m_header;
SDRDaemonProtectedBlock m_protectedBlock; RemoteProtectedBlock m_protectedBlock;
void init() void init()
{ {
@ -118,7 +119,7 @@ struct SDRDaemonSuperBlock
}; };
#pragma pack(pop) #pragma pack(pop)
struct SDRDaemonTxControlBlock struct RemoteTxControlBlock
{ {
bool m_complete; bool m_complete;
bool m_processed; bool m_processed;
@ -128,7 +129,7 @@ struct SDRDaemonTxControlBlock
QString m_dataAddress; QString m_dataAddress;
uint16_t m_dataPort; uint16_t m_dataPort;
SDRDaemonTxControlBlock() { RemoteTxControlBlock() {
m_complete = false; m_complete = false;
m_processed = false; m_processed = false;
m_frameIndex = 0; m_frameIndex = 0;
@ -139,7 +140,7 @@ struct SDRDaemonTxControlBlock
} }
}; };
struct SDRDaemonRxControlBlock struct RemoteRxControlBlock
{ {
int m_blockCount; //!< number of blocks received for this frame int m_blockCount; //!< number of blocks received for this frame
int m_originalCount; //!< number of original blocks received int m_originalCount; //!< number of original blocks received
@ -147,7 +148,7 @@ struct SDRDaemonRxControlBlock
bool m_metaRetrieved; //!< true if meta data (block zero) was retrieved bool m_metaRetrieved; //!< true if meta data (block zero) was retrieved
int m_frameIndex; //!< this frame index or -1 if unset int m_frameIndex; //!< this frame index or -1 if unset
SDRDaemonRxControlBlock() { RemoteRxControlBlock() {
m_blockCount = 0; m_blockCount = 0;
m_originalCount = 0; m_originalCount = 0;
m_recoveryCount = 0; m_recoveryCount = 0;
@ -156,18 +157,18 @@ struct SDRDaemonRxControlBlock
} }
}; };
class SDRDaemonDataBlock class RemoteDataBlock
{ {
public: public:
SDRDaemonDataBlock() { RemoteDataBlock() {
m_superBlocks = new SDRDaemonSuperBlock[256]; m_superBlocks = new RemoteSuperBlock[256];
} }
~SDRDaemonDataBlock() { ~RemoteDataBlock() {
delete[] m_superBlocks; delete[] m_superBlocks;
} }
SDRDaemonTxControlBlock m_txControlBlock; RemoteTxControlBlock m_txControlBlock;
SDRDaemonRxControlBlock m_rxControlBlock; RemoteRxControlBlock m_rxControlBlock;
SDRDaemonSuperBlock *m_superBlocks; RemoteSuperBlock *m_superBlocks;
}; };
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */ #endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */

Wyświetl plik

@ -1,11 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB. // // Copyright (C) 2018 Edouard Griffiths, F4EXB. //
// // // //
// SDRdaemon sink channel (Rx) data blocks queue // // Remtoe sink channel (Rx) data blocks queue //
// // // //
// SDRdaemon is a detached SDR front end that handles the interface with a // // SDRangel can serve as a remote SDR front end that handles the interface //
// physical device and sends or receives the I/Q samples stream to or from a // // with a physical device and sends or receives the I/Q samples stream via UDP //
// SDRangel instance via UDP. It is controlled via a Web REST API. // // to or from another SDRangel instance or any program implementing the same //
// protocol. The remote SDRangel is controlled via its Web REST API. //
// // // //
// This program is free software; you can redistribute it and/or modify // // 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 // // it under the terms of the GNU General Public License as published by //
@ -20,21 +21,21 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include <channel/remotedatablock.h>
#include <channel/remotedataqueue.h>
#include <QDebug> #include <QDebug>
#include <QMutexLocker> #include <QMutexLocker>
#include "channel/sdrdaemondataqueue.h"
#include "channel/sdrdaemondatablock.h"
SDRDaemonDataQueue::SDRDaemonDataQueue(QObject* parent) : RemoteDataQueue::RemoteDataQueue(QObject* parent) :
QObject(parent), QObject(parent),
m_lock(QMutex::Recursive), m_lock(QMutex::Recursive),
m_queue() m_queue()
{ {
} }
SDRDaemonDataQueue::~SDRDaemonDataQueue() RemoteDataQueue::~RemoteDataQueue()
{ {
SDRDaemonDataBlock* data; RemoteDataBlock* data;
while ((data = pop()) != 0) while ((data = pop()) != 0)
{ {
@ -43,7 +44,7 @@ SDRDaemonDataQueue::~SDRDaemonDataQueue()
} }
} }
void SDRDaemonDataQueue::push(SDRDaemonDataBlock* data, bool emitSignal) void RemoteDataQueue::push(RemoteDataBlock* data, bool emitSignal)
{ {
if (data) if (data)
{ {
@ -58,7 +59,7 @@ void SDRDaemonDataQueue::push(SDRDaemonDataBlock* data, bool emitSignal)
} }
} }
SDRDaemonDataBlock* SDRDaemonDataQueue::pop() RemoteDataBlock* RemoteDataQueue::pop()
{ {
QMutexLocker locker(&m_lock); QMutexLocker locker(&m_lock);
@ -72,14 +73,14 @@ SDRDaemonDataBlock* SDRDaemonDataQueue::pop()
} }
} }
int SDRDaemonDataQueue::size() int RemoteDataQueue::size()
{ {
QMutexLocker locker(&m_lock); QMutexLocker locker(&m_lock);
return m_queue.size(); return m_queue.size();
} }
void SDRDaemonDataQueue::clear() void RemoteDataQueue::clear()
{ {
QMutexLocker locker(&m_lock); QMutexLocker locker(&m_lock);
m_queue.clear(); m_queue.clear();

Wyświetl plik

@ -1,11 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB. // // Copyright (C) 2018 Edouard Griffiths, F4EXB. //
// // // //
// SDRdaemon sink channel (Rx) data blocks queue // // Remote sink channel (Rx) data blocks queue //
// // // //
// SDRdaemon is a detached SDR front end that handles the interface with a // // SDRangel can serve as a remote SDR front end that handles the interface //
// physical device and sends or receives the I/Q samples stream to or from a // // with a physical device and sends or receives the I/Q samples stream via UDP //
// SDRangel instance via UDP. It is controlled via a Web REST API. // // to or from another SDRangel instance or any program implementing the same //
// protocol. The remote SDRangel is controlled via its Web REST API. //
// // // //
// This program is free software; you can redistribute it and/or modify // // 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 // // it under the terms of the GNU General Public License as published by //
@ -20,24 +21,24 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_ #ifndef CHANNEL_REMOTEDATAQUEUE_H_
#define SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_ #define CHANNEL_REMOTEDATAQUEUE_H_
#include <QObject> #include <QObject>
#include <QMutex> #include <QMutex>
#include <QQueue> #include <QQueue>
class SDRDaemonDataBlock; class RemoteDataBlock;
class SDRDaemonDataQueue : public QObject { class RemoteDataQueue : public QObject {
Q_OBJECT Q_OBJECT
public: public:
SDRDaemonDataQueue(QObject* parent = NULL); RemoteDataQueue(QObject* parent = NULL);
~SDRDaemonDataQueue(); ~RemoteDataQueue();
void push(SDRDaemonDataBlock* dataBlock, bool emitSignal = true); //!< Push daa block onto queue void push(RemoteDataBlock* dataBlock, bool emitSignal = true); //!< Push daa block onto queue
SDRDaemonDataBlock* pop(); //!< Pop message from queue RemoteDataBlock* pop(); //!< Pop message from queue
int size(); //!< Returns queue size int size(); //!< Returns queue size
void clear(); //!< Empty queue void clear(); //!< Empty queue
@ -47,7 +48,7 @@ signals:
private: private:
QMutex m_lock; QMutex m_lock;
QQueue<SDRDaemonDataBlock*> m_queue; QQueue<RemoteDataBlock*> m_queue;
}; };
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_ */ #endif /* CHANNEL_REMOTEDATAQUEUE_H_ */

Wyświetl plik

@ -1,11 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB. // // Copyright (C) 2018 Edouard Griffiths, F4EXB. //
// // // //
// SDRdaemon sink channel (Rx) data blocks to read queue // // Remote sink channel (Rx) data blocks to read queue //
// // // //
// SDRdaemon is a detached SDR front end that handles the interface with a // // SDRangel can serve as a remote SDR front end that handles the interface //
// physical device and sends or receives the I/Q samples stream to or from a // // with a physical device and sends or receives the I/Q samples stream via UDP //
// SDRangel instance via UDP. It is controlled via a Web REST API. // // to or from another SDRangel instance or any program implementing the same //
// protocol. The remote SDRangel is controlled via its Web REST API. //
// // // //
// This program is free software; you can redistribute it and/or modify // // 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 // // it under the terms of the GNU General Public License as published by //
@ -20,12 +21,12 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#include "channel/sdrdaemondatablock.h" #include <channel/remotedatablock.h>
#include "channel/sdrdaemondatareadqueue.h" #include <channel/remotedatareadqueue.h>
const uint32_t SDRDaemonDataReadQueue::MinimumMaxSize = 10; const uint32_t RemoteDataReadQueue::MinimumMaxSize = 10;
SDRDaemonDataReadQueue::SDRDaemonDataReadQueue() : RemoteDataReadQueue::RemoteDataReadQueue() :
m_dataBlock(0), m_dataBlock(0),
m_maxSize(MinimumMaxSize), m_maxSize(MinimumMaxSize),
m_blockIndex(1), m_blockIndex(1),
@ -34,9 +35,9 @@ SDRDaemonDataReadQueue::SDRDaemonDataReadQueue() :
m_full(false) m_full(false)
{} {}
SDRDaemonDataReadQueue::~SDRDaemonDataReadQueue() RemoteDataReadQueue::~RemoteDataReadQueue()
{ {
SDRDaemonDataBlock* data; RemoteDataBlock* data;
while ((data = pop()) != 0) while ((data = pop()) != 0)
{ {
@ -45,13 +46,13 @@ SDRDaemonDataReadQueue::~SDRDaemonDataReadQueue()
} }
} }
void SDRDaemonDataReadQueue::push(SDRDaemonDataBlock* dataBlock) void RemoteDataReadQueue::push(RemoteDataBlock* dataBlock)
{ {
if (length() >= m_maxSize) if (length() >= m_maxSize)
{ {
qWarning("SDRDaemonDataReadQueue::push: queue is full"); qWarning("SDRDaemonDataReadQueue::push: queue is full");
m_full = true; // stop filling the queue m_full = true; // stop filling the queue
SDRDaemonDataBlock *data = m_dataReadQueue.takeLast(); RemoteDataBlock *data = m_dataReadQueue.takeLast();
delete data; delete data;
} }
@ -64,7 +65,7 @@ void SDRDaemonDataReadQueue::push(SDRDaemonDataBlock* dataBlock)
} }
} }
SDRDaemonDataBlock* SDRDaemonDataReadQueue::pop() RemoteDataBlock* RemoteDataReadQueue::pop()
{ {
if (m_dataReadQueue.isEmpty()) if (m_dataReadQueue.isEmpty())
{ {
@ -79,14 +80,14 @@ SDRDaemonDataBlock* SDRDaemonDataReadQueue::pop()
} }
} }
void SDRDaemonDataReadQueue::setSize(uint32_t size) void RemoteDataReadQueue::setSize(uint32_t size)
{ {
if (size != m_maxSize) { if (size != m_maxSize) {
m_maxSize = size < MinimumMaxSize ? MinimumMaxSize : size; m_maxSize = size < MinimumMaxSize ? MinimumMaxSize : size;
} }
} }
void SDRDaemonDataReadQueue::readSample(Sample& s, bool scaleForTx) void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
{ {
// depletion/repletion state // depletion/repletion state
if (m_dataBlock == 0) if (m_dataBlock == 0)
@ -109,7 +110,7 @@ void SDRDaemonDataReadQueue::readSample(Sample& s, bool scaleForTx)
} }
int sampleSize = m_dataBlock->m_superBlocks[m_blockIndex].m_header.m_sampleBytes * 2; int sampleSize = m_dataBlock->m_superBlocks[m_blockIndex].m_header.m_sampleBytes * 2;
uint32_t samplesPerBlock = SDRDaemonNbBytesPerBlock / sampleSize; uint32_t samplesPerBlock = RemoteNbBytesPerBlock / sampleSize;
if (m_sampleIndex < samplesPerBlock) if (m_sampleIndex < samplesPerBlock)
{ {
@ -122,7 +123,7 @@ void SDRDaemonDataReadQueue::readSample(Sample& s, bool scaleForTx)
m_sampleIndex = 0; m_sampleIndex = 0;
m_blockIndex++; m_blockIndex++;
if (m_blockIndex < SDRDaemonNbOrginalBlocks) if (m_blockIndex < RemoteNbOrginalBlocks)
{ {
convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx); convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx);
m_sampleIndex++; m_sampleIndex++;

Wyświetl plik

@ -1,11 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Edouard Griffiths, F4EXB. // // Copyright (C) 2018 Edouard Griffiths, F4EXB. //
// // // //
// SDRdaemon sink channel (Rx) data blocks to read queue // // Remote sink channel (Rx) data blocks to read queue //
// // // //
// SDRdaemon is a detached SDR front end that handles the interface with a // // SDRangel can serve as a remote SDR front end that handles the interface //
// physical device and sends or receives the I/Q samples stream to or from a // // with a physical device and sends or receives the I/Q samples stream via UDP //
// SDRangel instance via UDP. It is controlled via a Web REST API. // // to or from another SDRangel instance or any program implementing the same //
// protocol. The remote SDRangel is controlled via its Web REST API. //
// // // //
// This program is free software; you can redistribute it and/or modify // // 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 // // it under the terms of the GNU General Public License as published by //
@ -20,22 +21,22 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // // along with this program. If not, see <http://www.gnu.org/licenses/>. //
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRDAEMON_CHANNEL_SDRDAEMONDATAREADQUEUE_H_ #ifndef CHANNEL_REMOTEDATAREADQUEUE_H_
#define SDRDAEMON_CHANNEL_SDRDAEMONDATAREADQUEUE_H_ #define CHANNEL_REMOTEDATAREADQUEUE_H_
#include <QQueue> #include <QQueue>
class SDRDaemonDataBlock; class RemoteDataBlock;
class Sample; class Sample;
class SDRDaemonDataReadQueue class RemoteDataReadQueue
{ {
public: public:
SDRDaemonDataReadQueue(); RemoteDataReadQueue();
~SDRDaemonDataReadQueue(); ~RemoteDataReadQueue();
void push(SDRDaemonDataBlock* dataBlock); //!< push block on the queue void push(RemoteDataBlock* dataBlock); //!< push block on the queue
SDRDaemonDataBlock* pop(); //!< Pop block from the queue RemoteDataBlock* pop(); //!< Pop block from the queue
void readSample(Sample& s, bool scaleForTx = false); //!< Read sample from queue possibly scaling to Tx size void readSample(Sample& s, bool scaleForTx = false); //!< Read sample from queue possibly scaling to Tx size
uint32_t length() const { return m_dataReadQueue.size(); } //!< Returns queue length uint32_t length() const { return m_dataReadQueue.size(); } //!< Returns queue length
uint32_t size() const { return m_maxSize; } //!< Returns queue size (max length) uint32_t size() const { return m_maxSize; } //!< Returns queue size (max length)
@ -45,8 +46,8 @@ public:
static const uint32_t MinimumMaxSize; static const uint32_t MinimumMaxSize;
private: private:
QQueue<SDRDaemonDataBlock*> m_dataReadQueue; QQueue<RemoteDataBlock*> m_dataReadQueue;
SDRDaemonDataBlock *m_dataBlock; RemoteDataBlock *m_dataBlock;
uint32_t m_maxSize; uint32_t m_maxSize;
uint32_t m_blockIndex; uint32_t m_blockIndex;
uint32_t m_sampleIndex; uint32_t m_sampleIndex;
@ -90,4 +91,4 @@ private:
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATAREADQUEUE_H_ */ #endif /* CHANNEL_REMOTEDATAREADQUEUE_H_ */