1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-21 23:55:13 -05:00

Rename SDRDaemonSink device plugin to RemoteOutput (1)

This commit is contained in:
f4exb 2019-02-02 22:58:42 +01:00
parent 8ccab8acf4
commit ad66b4af49
52 changed files with 627 additions and 620 deletions

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -94,7 +94,7 @@ RemoteSink::~RemoteSink()
void RemoteSink::setTxDelay(int txDelay, int nbBlocksFEC)
{
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;
delay /= 128 + nbBlocksFEC;
m_txDelay = roundf(delay*1e6); // microseconds
@ -123,35 +123,34 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
if (m_txBlockIndex == 0)
{
struct timeval tv;
SDRDaemonMetaDataFEC metaData;
RemoteMetaDataFEC metaData;
gettimeofday(&tv, 0);
metaData.m_centerFrequency = m_centerFrequency;
metaData.m_sampleRate = m_sampleRate;
metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
metaData.m_sampleBits = SDR_RX_SAMP_SZ;
metaData.m_nbOriginalBlocks = SDRDaemonNbOrginalBlocks;
metaData.m_nbOriginalBlocks = RemoteNbOrginalBlocks;
metaData.m_nbFECBlocks = m_nbBlocksFEC;
metaData.m_tv_sec = tv.tv_sec;
metaData.m_tv_usec = tv.tv_usec;
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;
crc32.process_bytes(&metaData, 20);
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.m_header.m_frameIndex = m_frameCount;
superBlock.m_header.m_blockIndex = m_txBlockIndex;
superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ;
SDRDaemonMetaDataFEC *destMeta = (SDRDaemonMetaDataFEC *) &superBlock.m_protectedBlock;
RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &superBlock.m_protectedBlock;
*destMeta = metaData;
//memcpy((void *) &superBlock.m_protectedBlock, (const void *) &metaData, sizeof(SDRDaemonMetaDataFEC));
if (!(metaData == m_currentMetaFEC))
{
@ -172,7 +171,7 @@ void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVec
} // block zero
// 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
{
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_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_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;
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_txBlockIndex = 0;
@ -225,7 +224,7 @@ void RemoteSink::start()
{
qDebug("RemoteSink::start");
memset((void *) &m_currentMetaFEC, 0, sizeof(SDRDaemonMetaDataFEC));
memset((void *) &m_currentMetaFEC, 0, sizeof(RemoteMetaDataFEC));
if (m_running) {
stop();
@ -233,9 +232,9 @@ void RemoteSink::start()
m_sinkThread = new RemoteSinkThread();
connect(this,
SIGNAL(dataBlockAvailable(SDRDaemonDataBlock *)),
SIGNAL(dataBlockAvailable(RemoteDataBlock *)),
m_sinkThread,
SLOT(processDataBlock(SDRDaemonDataBlock *)),
SLOT(processDataBlock(RemoteDataBlock *)),
Qt::QueuedConnection);
m_sinkThread->startStop(true);
m_running = true;

View File

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

View File

@ -304,7 +304,7 @@ void RemoteSinkGUI::on_nbFECBlocks_valueChanged(int value)
void RemoteSinkGUI::updateTxDelayTime()
{
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;
delay /= 128 + m_settings.m_nbFECBlocks;
ui->txDelayTime->setText(tr("%1µs").arg(QString::number(delay*1e6, 'f', 0)));

View File

@ -22,9 +22,9 @@
#include "remotesinkthread.h"
#include <channel/remotedatablock.h>
#include <QUdpSocket>
#include "channel/sdrdaemondatablock.h"
#include "cm256.h"
MESSAGE_CLASS_DEFINITION(RemoteSinkThread::MsgStartStop, Message)
@ -86,48 +86,48 @@ void RemoteSinkThread::run()
qDebug("RemoteSinkThread::run: end");
}
void RemoteSinkThread::processDataBlock(SDRDaemonDataBlock *dataBlock)
void RemoteSinkThread::processDataBlock(RemoteDataBlock *dataBlock)
{
handleDataBlock(*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_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;
int nbBlocksFEC = dataBlock.m_txControlBlock.m_nbBlocksFEC;
int txDelay = dataBlock.m_txControlBlock.m_txDelay;
m_address.setAddress(dataBlock.m_txControlBlock.m_dataAddress);
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 (m_socket)
{
for (int i = 0; i < SDRDaemonNbOrginalBlocks; i++)
for (int i = 0; i < RemoteNbOrginalBlocks; i++)
{
// 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);
}
}
}
else
{
cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock);
cm256Params.OriginalCount = SDRDaemonNbOrginalBlocks;
cm256Params.BlockBytes = sizeof(RemoteProtectedBlock);
cm256Params.OriginalCount = RemoteNbOrginalBlocks;
cm256Params.RecoveryCount = nbBlocksFEC;
// Fill pointers to data
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i)
{
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;
@ -157,7 +157,7 @@ void RemoteSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock)
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
{
// 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);
}
}

View File

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

View File

@ -243,10 +243,10 @@ void RemoteSource::applySettings(const RemoteSourceSettings& settings, bool forc
m_settings = settings;
}
void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
void RemoteSource::handleDataBlock(RemoteDataBlock* 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");
}
@ -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
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);
CM256::cm256_encoder_params paramsCM256;
paramsCM256.BlockBytes = sizeof(SDRDaemonProtectedBlock); // never changes
paramsCM256.OriginalCount = SDRDaemonNbOrginalBlocks; // never changes
paramsCM256.BlockBytes = sizeof(RemoteProtectedBlock); // never changes
paramsCM256.OriginalCount = RemoteNbOrginalBlocks; // never changes
if (m_currentMeta.m_tv_sec == 0) {
paramsCM256.RecoveryCount = dataBlock->m_rxControlBlock.m_recoveryCount;
@ -287,8 +287,8 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
}
// update counters
if (dataBlock->m_rxControlBlock.m_originalCount < SDRDaemonNbOrginalBlocks - paramsCM256.RecoveryCount) {
m_nbUncorrectableErrors += SDRDaemonNbOrginalBlocks - paramsCM256.RecoveryCount - dataBlock->m_rxControlBlock.m_originalCount;
if (dataBlock->m_rxControlBlock.m_originalCount < RemoteNbOrginalBlocks - paramsCM256.RecoveryCount) {
m_nbUncorrectableErrors += RemoteNbOrginalBlocks - paramsCM256.RecoveryCount - dataBlock->m_rxControlBlock.m_originalCount;
} else {
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
{
int recoveryIndex = SDRDaemonNbOrginalBlocks - dataBlock->m_rxControlBlock.m_recoveryCount + ir;
int recoveryIndex = RemoteNbOrginalBlocks - dataBlock->m_rxControlBlock.m_recoveryCount + ir;
int blockIndex = m_cm256DescriptorBlocks[recoveryIndex].Index;
SDRDaemonProtectedBlock *recoveredBlock =
(SDRDaemonProtectedBlock *) m_cm256DescriptorBlocks[recoveryIndex].Block;
memcpy((void *) &(dataBlock->m_superBlocks[blockIndex].m_protectedBlock), recoveredBlock, sizeof(SDRDaemonProtectedBlock));
RemoteProtectedBlock *recoveredBlock =
(RemoteProtectedBlock *) m_cm256DescriptorBlocks[recoveryIndex].Block;
memcpy((void *) &(dataBlock->m_superBlocks[blockIndex].m_protectedBlock), recoveredBlock, sizeof(RemoteProtectedBlock));
if ((blockIndex == 0) && !dataBlock->m_rxControlBlock.m_metaRetrieved) {
dataBlock->m_rxControlBlock.m_metaRetrieved = true;
}
@ -318,7 +318,7 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
// Validate block zero and retrieve its data
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;
crc32.process_bytes(metaData, 20);
@ -349,14 +349,14 @@ void RemoteSource::handleDataBlock(SDRDaemonDataBlock* dataBlock)
void RemoteSource::handleData()
{
SDRDaemonDataBlock* dataBlock;
RemoteDataBlock* dataBlock;
while (m_running && ((dataBlock = m_dataQueue.pop()) != 0)) {
handleDataBlock(dataBlock);
}
}
void RemoteSource::printMeta(const QString& header, SDRDaemonMetaDataFEC *metaData)
void RemoteSource::printMeta(const QString& header, RemoteMetaDataFEC *metaData)
{
qDebug().noquote() << header << ": "
<< "|" << metaData->m_centerFrequency

View File

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

View File

@ -16,26 +16,26 @@
#include "remotesourcethread.h"
#include <channel/remotedatablock.h>
#include <channel/remotedataqueue.h>
#include <algorithm>
#include <QUdpSocket>
#include "cm256.h"
#include "channel/sdrdaemondataqueue.h"
#include "channel/sdrdaemondatablock.h"
MESSAGE_CLASS_DEFINITION(RemoteSourceThread::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(RemoteSourceThread::MsgDataBind, Message)
RemoteSourceThread::RemoteSourceThread(SDRDaemonDataQueue *dataQueue, QObject* parent) :
RemoteSourceThread::RemoteSourceThread(RemoteDataQueue *dataQueue, QObject* parent) :
QThread(parent),
m_running(false),
m_dataQueue(dataQueue),
m_address(QHostAddress::LocalHost),
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);
}
@ -128,7 +128,7 @@ void RemoteSourceThread::handleInputMessages()
void RemoteSourceThread::readPendingDatagrams()
{
SDRDaemonSuperBlock superBlock;
RemoteSuperBlock superBlock;
qint64 size;
while (m_socket->hasPendingDatagrams())
@ -136,15 +136,15 @@ void RemoteSourceThread::readPendingDatagrams()
QHostAddress sender;
quint16 senderPort = 0;
//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;
// create the first block for this index
if (m_dataBlocks[dataBlockIndex] == 0) {
m_dataBlocks[dataBlockIndex] = new SDRDaemonDataBlock();
m_dataBlocks[dataBlockIndex] = new RemoteDataBlock();
}
if (m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_frameIndex < 0)
@ -159,9 +159,9 @@ void RemoteSourceThread::readPendingDatagrams()
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_dataBlocks[dataBlockIndex] = new SDRDaemonDataBlock();
m_dataBlocks[dataBlockIndex] = new RemoteDataBlock();
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;
}
if (superBlock.m_header.m_blockIndex < SDRDaemonNbOrginalBlocks) {
if (superBlock.m_header.m_blockIndex < RemoteNbOrginalBlocks) {
m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_originalCount++;
} else {
m_dataBlocks[dataBlockIndex]->m_rxControlBlock.m_recoveryCount++;

View File

@ -25,8 +25,8 @@
#include "util/message.h"
#include "util/messagequeue.h"
class SDRDaemonDataQueue;
class SDRDaemonDataBlock;
class RemoteDataQueue;
class RemoteDataBlock;
class QUdpSocket;
class RemoteSourceThread : public QThread {
@ -74,7 +74,7 @@ public:
}
};
RemoteSourceThread(SDRDaemonDataQueue *dataQueue, QObject* parent = 0);
RemoteSourceThread(RemoteDataQueue *dataQueue, QObject* parent = 0);
~RemoteSourceThread();
void startStop(bool start);
@ -86,13 +86,13 @@ private:
volatile bool m_running;
MessageQueue m_inputMessageQueue;
SDRDaemonDataQueue *m_dataQueue;
RemoteDataQueue *m_dataQueue;
QHostAddress m_address;
QUdpSocket *m_socket;
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 stopWork();

View File

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

View File

@ -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:
![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.

View File

@ -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:
![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.

View File

@ -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:
![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.

View File

@ -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)

View File

@ -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 //
// //
@ -19,6 +19,7 @@
// Original code is posted at: https://cppcodetips.wordpress.com/2014/01/29/udp-socket-class-in-c/
#include "UDPSocket.h"
#include <errno.h>
#include <cstring>
#include <fcntl.h>

View File

@ -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 //
// //

View File

@ -1,14 +1,14 @@
<h1>SDRdaemon sink plugin</h1>
<h1>Remote output plugin</h1>
<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.
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.
@ -18,7 +18,7 @@ The plugin will be built only if the [CM256cc library](https://github.com/f4exb/
<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>
@ -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>
![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>
@ -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>
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>
![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>
@ -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>
![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>
@ -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>
![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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,9 +22,9 @@
#include "dsp/samplesourcefifo.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),
m_running(false),
m_samplesChunkSize(0),
@ -32,22 +32,22 @@ SDRdaemonSinkThread::SDRdaemonSinkThread(SampleSourceFifo* sampleFifo, QObject*
m_samplesCount(0),
m_chunkCorrection(0),
m_samplerate(0),
m_throttlems(SDRDAEMONSINK_THROTTLE_MS),
m_throttlems(REMOTEOUTPUT_THROTTLE_MS),
m_maxThrottlems(50),
m_throttleToggle(false)
{
}
SDRdaemonSinkThread::~SDRdaemonSinkThread()
RemoteOutputThread::~RemoteOutputThread()
{
if (m_running) {
stopWork();
}
}
void SDRdaemonSinkThread::startWork()
void RemoteOutputThread::startWork()
{
qDebug() << "SDRdaemonSinkThread::startWork: ";
qDebug() << "RemoteOutputThread::startWork: ";
m_udpSinkFEC.start();
m_maxThrottlems = 0;
m_startWaitMutex.lock();
@ -58,19 +58,19 @@ void SDRdaemonSinkThread::startWork()
m_startWaitMutex.unlock();
}
void SDRdaemonSinkThread::stopWork()
void RemoteOutputThread::stopWork()
{
qDebug() << "SDRdaemonSinkThread::stopWork";
qDebug() << "RemoteOutputThread::stopWork";
m_running = false;
wait();
m_udpSinkFEC.stop();
}
void SDRdaemonSinkThread::setSamplerate(int samplerate)
void RemoteOutputThread::setSamplerate(int samplerate)
{
if (samplerate != m_samplerate)
{
qDebug() << "SDRdaemonSinkThread::setSamplerate:"
qDebug() << "RemoteOutputThread::setSamplerate:"
<< " new:" << samplerate
<< " old:" << m_samplerate;
@ -97,7 +97,7 @@ void SDRdaemonSinkThread::setSamplerate(int samplerate)
}
}
void SDRdaemonSinkThread::run()
void RemoteOutputThread::run()
{
m_running = true;
m_startWaiter.wakeAll();
@ -110,13 +110,13 @@ void SDRdaemonSinkThread::run()
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()));
}
void SDRdaemonSinkThread::tick()
void RemoteOutputThread::tick()
{
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();
return m_samplesCount;

View File

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

View File

@ -14,13 +14,15 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "udpsinkfec.h"
#include <QDebug>
#include <boost/crc.hpp>
#include <boost/cstdint.hpp>
#include "util/timeutil.h"
#include "udpsinkfec.h"
#include "udpsinkfecworker.h"
@ -38,8 +40,8 @@ UDPSinkFEC::UDPSinkFEC() :
m_remoteAddress("127.0.0.1"),
m_remotePort(9090)
{
memset((char *) m_txBlocks, 0, 4*256*sizeof(SDRDaemonSuperBlock));
memset((char *) &m_superBlock, 0, sizeof(SDRDaemonSuperBlock));
memset((char *) m_txBlocks, 0, 4*256*sizeof(RemoteSuperBlock));
memset((char *) &m_superBlock, 0, sizeof(RemoteSuperBlock));
m_currentMetaFEC.init();
m_bufMeta = 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 the number of actual blocks including FEC blocks gives the block (i.e. UDP block) process time
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);
m_txDelay = delay * 1e6;
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
{
SDRDaemonMetaDataFEC metaData;
RemoteMetaDataFEC metaData;
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_sampleBits = SDR_RX_SAMP_SZ;
SDRDaemonMetaDataFEC *destMeta = (SDRDaemonMetaDataFEC *) &m_superBlock.m_protectedBlock;
RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &m_superBlock.m_protectedBlock;
*destMeta = metaData;
//memcpy((char *) &m_superBlock.m_protectedBlock, (const char *) &metaData, sizeof(SDRDaemonMetaDataFEC));
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
}
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
{

View File

@ -14,9 +14,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFEC_H_
#define PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFEC_H_
#ifndef PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_
#define PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_
#include <channel/remotedatablock.h>
#include <string.h>
#include <cstddef>
@ -26,7 +27,6 @@
#include "dsp/dsptypes.h"
#include "util/CRC64.h"
#include "channel/sdrdaemondatablock.h"
class UDPSinkFECWorker;
@ -86,12 +86,12 @@ private:
uint8_t* m_bufMeta;
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
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
SDRDaemonSuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC
SDRDaemonSuperBlock m_superBlock; //!< current super block being built
RemoteSuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC
RemoteSuperBlock m_superBlock; //!< current super block being built
int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row
int m_txBlocksIndex; //!< Current index of Tx blocks row
uint16_t m_frameCount; //!< transmission frame count
@ -102,4 +102,4 @@ private:
uint16_t m_remotePort;
};
#endif /* PLUGINS_SAMPLESINK_SDRDAEMONSINK_UDPSINKFEC_H_ */
#endif /* PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_ */

View File

@ -14,9 +14,10 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "udpsinkfecworker.h"
#include <QUdpSocket>
#include "udpsinkfecworker.h"
MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgUDPFECEncodeAndSend, Message)
MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgConfigureRemoteAddress, Message)
@ -81,7 +82,7 @@ void UDPSinkFECWorker::run()
qDebug("UDPSinkFECWorker::process: stopped");
}
void UDPSinkFECWorker::pushTxFrame(SDRDaemonSuperBlock *txBlocks,
void UDPSinkFECWorker::pushTxFrame(RemoteSuperBlock *txBlocks,
uint32_t nbBlocksFEC,
uint32_t txDelay,
uint16_t frameIndex)
@ -117,7 +118,7 @@ void UDPSinkFECWorker::handleInputMessages()
else if (MsgStartStop::match(*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()) {
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_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 (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], SDRDaemonUdpSize, m_remoteHostAddress, m_remotePort);
m_udpSocket->writeDatagram((const char *) &txBlockx[i], RemoteUdpSize, m_remoteHostAddress, m_remotePort);
usleep(txDelay);
}
}
}
else
{
cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock);
cm256Params.OriginalCount = SDRDaemonNbOrginalBlocks;
cm256Params.BlockBytes = sizeof(RemoteProtectedBlock);
cm256Params.OriginalCount = RemoteNbOrginalBlocks;
cm256Params.RecoveryCount = nbBlocksFEC;
@ -159,7 +159,7 @@ void UDPSinkFECWorker::encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i)
{
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;
@ -188,13 +188,13 @@ void UDPSinkFECWorker::encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t
{
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
{
#ifdef SDRDAEMON_PUNCTURE
if (i == SDRDAEMON_PUNCTURE) {
#ifdef REMOTE_PUNCTURE
if (i == REMOTE_PUNCTURE) {
continue;
}
#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);
}
}

View File

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

View File

@ -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)

View File

@ -50,8 +50,8 @@ SDRdaemonSourceBuffer::SDRdaemonSourceBuffer() :
m_tvOut_sec = 0;
m_tvOut_usec = 0;
m_readNbBytes = 1;
m_paramsCM256.BlockBytes = sizeof(SDRDaemonProtectedBlock); // never changes
m_paramsCM256.OriginalCount = SDRDaemonNbOrginalBlocks; // never changes
m_paramsCM256.BlockBytes = sizeof(RemoteProtectedBlock); // never changes
m_paramsCM256.OriginalCount = RemoteNbOrginalBlocks; // never changes
if (!m_cm256.isInitialized()) {
m_cm256_OK = false;
@ -81,7 +81,7 @@ void SDRdaemonSourceBuffer::initDecodeAllSlots()
m_decoderSlots[i].m_decoded = false;
m_decoderSlots[i].m_metaRetrieved = false;
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;
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()
@ -190,7 +190,7 @@ void SDRdaemonSourceBuffer::checkSlotData(int slotIndex)
void SDRdaemonSourceBuffer::writeData(char *array)
{
SDRDaemonSuperBlock *superBlock = (SDRDaemonSuperBlock *) array;
RemoteSuperBlock *superBlock = (RemoteSuperBlock *) array;
int frameIndex = superBlock->m_header.m_frameIndex;
int decoderIndex = frameIndex % nbDecoderSlots;
@ -214,7 +214,7 @@ void SDRdaemonSourceBuffer::writeData(char *array)
// 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 blockCount = m_decoderSlots[decoderIndex].m_blockCount;
@ -226,7 +226,7 @@ void SDRdaemonSourceBuffer::writeData(char *array)
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_originalCount++;
@ -241,14 +241,14 @@ void SDRdaemonSourceBuffer::writeData(char *array)
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;
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.OriginalCount = SDRDaemonNbOrginalBlocks; // never changes
m_paramsCM256.BlockBytes = sizeof(RemoteProtectedBlock); // never changes
m_paramsCM256.OriginalCount = RemoteNbOrginalBlocks; // never changes
if (m_decoderSlots[decoderIndex].m_metaRetrieved) {
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
{
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;
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
{
SDRDaemonMetaDataFEC *metaData = (SDRDaemonMetaDataFEC *) recoveredBlock;
RemoteMetaDataFEC *metaData = (RemoteMetaDataFEC *) recoveredBlock;
boost::crc_32_type crc32;
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
{
SDRDaemonMetaDataFEC *metaData = getMetaData(decoderIndex);
RemoteMetaDataFEC *metaData = getMetaData(decoderIndex);
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 << ": "
<< "|" << metaData->m_centerFrequency

View File

@ -17,12 +17,12 @@
#ifndef PLUGINS_SAMPLESOURCE_SDRDAEMONSOURCE_SDRDAEMONSOURCEBUFFER_H_
#define PLUGINS_SAMPLESOURCE_SDRDAEMONSOURCE_SDRDAEMONSOURCEBUFFER_H_
#include <channel/remotedatablock.h>
#include <QString>
#include <QDebug>
#include <cstdlib>
#include "cm256.h"
#include "util/movingaverage.h"
#include "channel/sdrdaemondatablock.h"
#define SDRDAEMONSOURCE_UDPSIZE 512 // UDP payload size
@ -40,7 +40,7 @@ public:
uint8_t *readData(int32_t length); //!< Read data from buffer
// meta data
const SDRDaemonMetaDataFEC& getCurrentMeta() const { return m_currentMeta; }
const RemoteMetaDataFEC& getCurrentMeta() const { return m_currentMeta; }
// samples timestamp
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:
static const int nbDecoderSlots = SDRDAEMONSOURCE_NBDECODERSLOTS;
@ -113,16 +113,16 @@ private:
#pragma pack(push, 1)
struct BufferFrame
{
SDRDaemonProtectedBlock m_blocks[SDRDaemonNbOrginalBlocks - 1];
RemoteProtectedBlock m_blocks[RemoteNbOrginalBlocks - 1];
};
#pragma pack(pop)
struct DecoderSlot
{
SDRDaemonProtectedBlock m_blockZero; //!< First block of a frame. Has meta data.
SDRDaemonProtectedBlock m_originalBlocks[SDRDaemonNbOrginalBlocks]; //!< Original blocks retrieved directly or by later FEC
SDRDaemonProtectedBlock m_recoveryBlocks[SDRDaemonNbOrginalBlocks]; //!< Recovery blocks (FEC blocks) with max size
CM256::cm256_block m_cm256DescriptorBlocks[SDRDaemonNbOrginalBlocks]; //!< CM256 decoder descriptors (block addresses and block indexes)
RemoteProtectedBlock m_blockZero; //!< First block of a frame. Has meta data.
RemoteProtectedBlock m_originalBlocks[RemoteNbOrginalBlocks]; //!< Original blocks retrieved directly or by later FEC
RemoteProtectedBlock m_recoveryBlocks[RemoteNbOrginalBlocks]; //!< Recovery blocks (FEC blocks) with max size
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_originalCount; //!< number of original 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
};
SDRDaemonMetaDataFEC m_currentMeta; //!< Stored current meta data
RemoteMetaDataFEC m_currentMeta; //!< Stored current meta data
CM256::cm256_encoder_params m_paramsCM256; //!< CM256 decoder parameters block
DecoderSlot m_decoderSlots[nbDecoderSlots]; //!< CM256 decoding control/buffer slots
BufferFrame m_frames[nbDecoderSlots]; //!< Samples buffer
@ -165,7 +165,7 @@ private:
CM256 m_cm256; //!< CM256 library
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) {
// 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) {
// 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 (SDRDaemonMetaDataFEC *) &m_decoderSlots[slotIndex].m_blockZero;
return (RemoteMetaDataFEC *) &m_decoderSlots[slotIndex].m_blockZero;
}
inline void resetOriginalBlocks(int slotIndex)
{
// 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_frames[slotIndex].m_blocks, 0, (SDRDaemonNbOrginalBlocks - 1) * sizeof(SDRDaemonProtectedBlock));
memset((void *) &m_decoderSlots[slotIndex].m_blockZero, 0, sizeof(RemoteProtectedBlock));
memset((void *) m_frames[slotIndex].m_blocks, 0, (RemoteNbOrginalBlocks - 1) * sizeof(RemoteProtectedBlock));
}
void initDecodeAllSlots();
@ -210,7 +210,7 @@ private:
void checkSlotData(int slotIndex);
void initDecodeSlot(int slotIndex);
static void printMeta(const QString& header, SDRDaemonMetaDataFEC *metaData);
static void printMeta(const QString& header, RemoteMetaDataFEC *metaData);
};

View File

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

View File

@ -43,7 +43,7 @@ public:
void stop();
void configureUDPLink(const QString& address, quint16 port);
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; }
int getSampleRate() const { return m_samplerate; }
int getCenterFrequency() const { return m_centerFrequency * 1000; }

View File

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

View File

@ -1,7 +1,7 @@
project(sdrdaemonsink)
project(remoteoutput)
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)
message(STATUS "SDRdaemonFEC: use SSSE3 SIMD" )
@ -12,20 +12,20 @@ else()
return()
endif()
set(sdrdaemonsink_SOURCES
${PLUGIN_PREFIX}/sdrdaemonsinkoutput.cpp
${PLUGIN_PREFIX}/sdrdaemonsinkplugin.cpp
${PLUGIN_PREFIX}/sdrdaemonsinksettings.cpp
${PLUGIN_PREFIX}/sdrdaemonsinkthread.cpp
set(remoteoutput_SOURCES
${PLUGIN_PREFIX}/remoteoutput.cpp
${PLUGIN_PREFIX}/remoteoutputplugin.cpp
${PLUGIN_PREFIX}/remoteoutputsettings.cpp
${PLUGIN_PREFIX}/remoteoutputthread.cpp
${PLUGIN_PREFIX}/udpsinkfec.cpp
${PLUGIN_PREFIX}/udpsinkfecworker.cpp
)
set(sdrdaemonsink_HEADERS
${PLUGIN_PREFIX}/sdrdaemonsinkoutput.h
${PLUGIN_PREFIX}/sdrdaemonsinkplugin.h
${PLUGIN_PREFIX}/sdrdaemonsinksettings.h
${PLUGIN_PREFIX}/sdrdaemonsinkthread.h
set(remoteoutput_HEADERS
${PLUGIN_PREFIX}/remoteoutput.h
${PLUGIN_PREFIX}/remoteoutputplugin.h
${PLUGIN_PREFIX}/remoteoutputsettings.h
${PLUGIN_PREFIX}/remoteoutputthread.h
${PLUGIN_PREFIX}/udpsinkfec.h
${PLUGIN_PREFIX}/udpsinkfecworker.h
)
@ -51,20 +51,20 @@ add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
add_library(outputsdrdaemonsinksrv SHARED
${sdrdaemonsink_SOURCES}
${sdrdaemonsink_HEADERS_MOC}
add_library(outputremotesrv SHARED
${remoteoutput_SOURCES}
${remoteoutput_HEADERS_MOC}
)
if (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsinksrv
target_link_libraries(outputremotesrv
${QT_LIBRARIES}
sdrbase
swagger
cm256cc
)
else (BUILD_DEBIAN)
target_link_libraries(outputsdrdaemonsinksrv
target_link_libraries(outputremotesrv
${QT_LIBRARIES}
sdrbase
swagger
@ -72,6 +72,6 @@ target_link_libraries(outputsdrdaemonsinksrv
)
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)

View File

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

View File

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

View File

@ -1,11 +1,12 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 //
// physical device and sends or receives the I/Q samples stream to or from a //
// SDRangel instance via UDP. It is controlled via a Web REST API. //
// SDRangel can serve as a remote SDR front end that handles the interface //
// with a physical device and sends or receives the I/Q samples stream via UDP //
// 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 //
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <channel/remotedatablock.h>
#include <channel/remotedataqueue.h>
#include <QDebug>
#include <QMutexLocker>
#include "channel/sdrdaemondataqueue.h"
#include "channel/sdrdaemondatablock.h"
SDRDaemonDataQueue::SDRDaemonDataQueue(QObject* parent) :
RemoteDataQueue::RemoteDataQueue(QObject* parent) :
QObject(parent),
m_lock(QMutex::Recursive),
m_queue()
{
}
SDRDaemonDataQueue::~SDRDaemonDataQueue()
RemoteDataQueue::~RemoteDataQueue()
{
SDRDaemonDataBlock* data;
RemoteDataBlock* data;
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)
{
@ -58,7 +59,7 @@ void SDRDaemonDataQueue::push(SDRDaemonDataBlock* data, bool emitSignal)
}
}
SDRDaemonDataBlock* SDRDaemonDataQueue::pop()
RemoteDataBlock* RemoteDataQueue::pop()
{
QMutexLocker locker(&m_lock);
@ -72,14 +73,14 @@ SDRDaemonDataBlock* SDRDaemonDataQueue::pop()
}
}
int SDRDaemonDataQueue::size()
int RemoteDataQueue::size()
{
QMutexLocker locker(&m_lock);
return m_queue.size();
}
void SDRDaemonDataQueue::clear()
void RemoteDataQueue::clear()
{
QMutexLocker locker(&m_lock);
m_queue.clear();

View File

@ -1,11 +1,12 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 //
// physical device and sends or receives the I/Q samples stream to or from a //
// SDRangel instance via UDP. It is controlled via a Web REST API. //
// SDRangel can serve as a remote SDR front end that handles the interface //
// with a physical device and sends or receives the I/Q samples stream via UDP //
// 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 //
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_
#define SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_
#ifndef CHANNEL_REMOTEDATAQUEUE_H_
#define CHANNEL_REMOTEDATAQUEUE_H_
#include <QObject>
#include <QMutex>
#include <QQueue>
class SDRDaemonDataBlock;
class RemoteDataBlock;
class SDRDaemonDataQueue : public QObject {
class RemoteDataQueue : public QObject {
Q_OBJECT
public:
SDRDaemonDataQueue(QObject* parent = NULL);
~SDRDaemonDataQueue();
RemoteDataQueue(QObject* parent = NULL);
~RemoteDataQueue();
void push(SDRDaemonDataBlock* dataBlock, bool emitSignal = true); //!< Push daa block onto queue
SDRDaemonDataBlock* pop(); //!< Pop message from queue
void push(RemoteDataBlock* dataBlock, bool emitSignal = true); //!< Push daa block onto queue
RemoteDataBlock* pop(); //!< Pop message from queue
int size(); //!< Returns queue size
void clear(); //!< Empty queue
@ -47,7 +48,7 @@ signals:
private:
QMutex m_lock;
QQueue<SDRDaemonDataBlock*> m_queue;
QQueue<RemoteDataBlock*> m_queue;
};
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_ */
#endif /* CHANNEL_REMOTEDATAQUEUE_H_ */

View File

@ -1,11 +1,12 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 //
// physical device and sends or receives the I/Q samples stream to or from a //
// SDRangel instance via UDP. It is controlled via a Web REST API. //
// SDRangel can serve as a remote SDR front end that handles the interface //
// with a physical device and sends or receives the I/Q samples stream via UDP //
// 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 //
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "channel/sdrdaemondatablock.h"
#include "channel/sdrdaemondatareadqueue.h"
#include <channel/remotedatablock.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_maxSize(MinimumMaxSize),
m_blockIndex(1),
@ -34,9 +35,9 @@ SDRDaemonDataReadQueue::SDRDaemonDataReadQueue() :
m_full(false)
{}
SDRDaemonDataReadQueue::~SDRDaemonDataReadQueue()
RemoteDataReadQueue::~RemoteDataReadQueue()
{
SDRDaemonDataBlock* data;
RemoteDataBlock* data;
while ((data = pop()) != 0)
{
@ -45,13 +46,13 @@ SDRDaemonDataReadQueue::~SDRDaemonDataReadQueue()
}
}
void SDRDaemonDataReadQueue::push(SDRDaemonDataBlock* dataBlock)
void RemoteDataReadQueue::push(RemoteDataBlock* dataBlock)
{
if (length() >= m_maxSize)
{
qWarning("SDRDaemonDataReadQueue::push: queue is full");
m_full = true; // stop filling the queue
SDRDaemonDataBlock *data = m_dataReadQueue.takeLast();
RemoteDataBlock *data = m_dataReadQueue.takeLast();
delete data;
}
@ -64,7 +65,7 @@ void SDRDaemonDataReadQueue::push(SDRDaemonDataBlock* dataBlock)
}
}
SDRDaemonDataBlock* SDRDaemonDataReadQueue::pop()
RemoteDataBlock* RemoteDataReadQueue::pop()
{
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) {
m_maxSize = size < MinimumMaxSize ? MinimumMaxSize : size;
}
}
void SDRDaemonDataReadQueue::readSample(Sample& s, bool scaleForTx)
void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
{
// depletion/repletion state
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;
uint32_t samplesPerBlock = SDRDaemonNbBytesPerBlock / sampleSize;
uint32_t samplesPerBlock = RemoteNbBytesPerBlock / sampleSize;
if (m_sampleIndex < samplesPerBlock)
{
@ -122,7 +123,7 @@ void SDRDaemonDataReadQueue::readSample(Sample& s, bool scaleForTx)
m_sampleIndex = 0;
m_blockIndex++;
if (m_blockIndex < SDRDaemonNbOrginalBlocks)
if (m_blockIndex < RemoteNbOrginalBlocks)
{
convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx);
m_sampleIndex++;

View File

@ -1,11 +1,12 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 //
// physical device and sends or receives the I/Q samples stream to or from a //
// SDRangel instance via UDP. It is controlled via a Web REST API. //
// SDRangel can serve as a remote SDR front end that handles the interface //
// with a physical device and sends or receives the I/Q samples stream via UDP //
// 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 //
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRDAEMON_CHANNEL_SDRDAEMONDATAREADQUEUE_H_
#define SDRDAEMON_CHANNEL_SDRDAEMONDATAREADQUEUE_H_
#ifndef CHANNEL_REMOTEDATAREADQUEUE_H_
#define CHANNEL_REMOTEDATAREADQUEUE_H_
#include <QQueue>
class SDRDaemonDataBlock;
class RemoteDataBlock;
class Sample;
class SDRDaemonDataReadQueue
class RemoteDataReadQueue
{
public:
SDRDaemonDataReadQueue();
~SDRDaemonDataReadQueue();
RemoteDataReadQueue();
~RemoteDataReadQueue();
void push(SDRDaemonDataBlock* dataBlock); //!< push block on the queue
SDRDaemonDataBlock* pop(); //!< Pop block from the queue
void push(RemoteDataBlock* dataBlock); //!< push block on 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
uint32_t length() const { return m_dataReadQueue.size(); } //!< Returns queue length
uint32_t size() const { return m_maxSize; } //!< Returns queue size (max length)
@ -45,8 +46,8 @@ public:
static const uint32_t MinimumMaxSize;
private:
QQueue<SDRDaemonDataBlock*> m_dataReadQueue;
SDRDaemonDataBlock *m_dataBlock;
QQueue<RemoteDataBlock*> m_dataReadQueue;
RemoteDataBlock *m_dataBlock;
uint32_t m_maxSize;
uint32_t m_blockIndex;
uint32_t m_sampleIndex;
@ -90,4 +91,4 @@ private:
#endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATAREADQUEUE_H_ */
#endif /* CHANNEL_REMOTEDATAREADQUEUE_H_ */