1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-25 01:18:38 -05:00

Compare commits

...

6 Commits

32 changed files with 100 additions and 251 deletions

View File

@ -85,7 +85,6 @@ void RemoteSinkSender::sendDataBlock(RemoteDataBlock *dataBlock)
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;
RemoteSuperBlock *txBlockx = dataBlock->m_superBlocks;
@ -94,11 +93,8 @@ void RemoteSinkSender::sendDataBlock(RemoteDataBlock *dataBlock)
{
if (m_socket)
{
for (int i = 0; i < RemoteNbOrginalBlocks; i++)
{
// send block via UDP
for (int i = 0; i < RemoteNbOrginalBlocks; i++) { // send block via UDP
m_socket->writeDatagram((const char*)&txBlockx[i], (qint64 ) RemoteUdpSize, m_address, dataPort);
std::this_thread::sleep_for(std::chrono::microseconds(txDelay));
}
}
}
@ -139,11 +135,8 @@ void RemoteSinkSender::sendDataBlock(RemoteDataBlock *dataBlock)
// Transmit all blocks
if (m_socket)
{
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
{
// send block via UDP
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++) { // send block via UDP
m_socket->writeDatagram((const char*)&txBlockx[i], (qint64 ) RemoteUdpSize, m_address, dataPort);
std::this_thread::sleep_for(std::chrono::microseconds(txDelay));
}
}
}

View File

@ -36,7 +36,6 @@ RemoteSinkSink::RemoteSinkSink() :
m_frequencyOffset(0),
m_basebandSampleRate(48000),
m_nbBlocksFEC(0),
m_txDelay(35),
m_dataAddress("127.0.0.1"),
m_dataPort(9090)
{
@ -165,7 +164,6 @@ void RemoteSinkSink::feed(const SampleVector::const_iterator& begin, const Sampl
m_dataBlock->m_txControlBlock.m_processed = false;
m_dataBlock->m_txControlBlock.m_complete = true;
m_dataBlock->m_txControlBlock.m_nbBlocksFEC = m_nbBlocksFEC;
m_dataBlock->m_txControlBlock.m_txDelay = m_txDelay;
m_dataBlock->m_txControlBlock.m_dataAddress = m_dataAddress;
m_dataBlock->m_txControlBlock.m_dataPort = m_dataPort;

View File

@ -61,7 +61,6 @@ private:
int64_t m_frequencyOffset;
uint32_t m_basebandSampleRate;
int m_nbBlocksFEC;
int m_txDelay;
QString m_dataAddress;
uint16_t m_dataPort;

View File

@ -330,12 +330,9 @@ void RemoteSourceGUI::on_dataPort_returnPressed()
bool dataOk;
int dataPort = ui->dataPort->text().toInt(&dataOk);
if((!dataOk) || (dataPort < 1024) || (dataPort > 65535))
{
if ((!dataOk) || (dataPort < 1024) || (dataPort > 65535)) {
return;
}
else
{
} else {
m_settings.m_dataPort = dataPort;
}
@ -350,8 +347,7 @@ void RemoteSourceGUI::on_dataApplyButton_clicked(bool checked)
bool dataOk;
int udpDataPort = ui->dataPort->text().toInt(&dataOk);
if((dataOk) && (udpDataPort >= 1024) && (udpDataPort < 65535))
{
if ((dataOk) && (udpDataPort >= 1024) && (udpDataPort < 65535)) {
m_settings.m_dataPort = udpDataPort;
}

View File

@ -139,7 +139,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="dataApplyButton">
<property name="maximumSize">
<size>
<width>30</width>

View File

@ -35,7 +35,9 @@ RemoteSourceSource::RemoteSourceSource() :
}
RemoteSourceSource::~RemoteSourceSource()
{}
{
stop();
}
void RemoteSourceSource::pull(SampleVector::iterator begin, unsigned int nbSamples)
{
@ -105,7 +107,7 @@ void RemoteSourceSource::stop()
{
stopWorker();
m_sourceWorker->deleteLater();
m_sourceWorker = 0;
m_sourceWorker = nullptr;
}
m_running = false;
@ -276,4 +278,4 @@ void RemoteSourceSource::applyChannelSettings(int channelSampleRate, bool force)
}
m_channelSampleRate = channelSampleRate;
}
}

View File

@ -19,9 +19,9 @@
#include <channel/remotedataqueue.h>
#include <algorithm>
#include <QUdpSocket>
#include "cm256cc/cm256.h"
#include <QThread>
#include "cm256cc/cm256.h"
#include "remotesourceworker.h"
MESSAGE_CLASS_DEFINITION(RemoteSourceWorker::MsgDataBind, Message)
@ -31,10 +31,18 @@ RemoteSourceWorker::RemoteSourceWorker(RemoteDataQueue *dataQueue, QObject* pare
m_running(false),
m_dataQueue(dataQueue),
m_address(QHostAddress::LocalHost),
m_socket(nullptr)
m_socket(this),
m_mutex(QMutex::Recursive),
m_sampleRate(0)
{
std::fill(m_dataBlocks, m_dataBlocks+4, (RemoteDataBlock *) 0);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
connect(&m_socket, SIGNAL(readyRead()),this, SLOT(recv()));
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
connect(&m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, &APRSWorker::errorOccurred);
#else
connect(&m_socket, &QAbstractSocket::errorOccurred, this, &RemoteSourceWorker::errorOccurred);
#endif
}
RemoteSourceWorker::~RemoteSourceWorker()
@ -48,19 +56,43 @@ void RemoteSourceWorker::dataBind(const QString& address, uint16_t port)
m_inputMessageQueue.push(msg);
}
void RemoteSourceWorker::startWork()
bool RemoteSourceWorker::startWork()
{
qDebug("RemoteSourceWorker::startWork");
m_socket = new QUdpSocket(this);
m_running = false;
QMutexLocker mutexLocker(&m_mutex);
m_socket.setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, getDataSocketBufferSize(m_sampleRate));
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
connect(thread(), SIGNAL(started()), this, SLOT(started()));
connect(thread(), SIGNAL(finished()), this, SLOT(finished()));
m_running = true;
return m_running;
}
void RemoteSourceWorker::started()
{
disconnect(thread(), SIGNAL(started()), this, SLOT(started()));
}
void RemoteSourceWorker::stopWork()
{
qDebug("RemoteSourceWorker::stopWork");
delete m_socket;
m_socket = nullptr;
QMutexLocker mutexLocker(&m_mutex);
disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
}
void RemoteSourceWorker::finished()
{
// Close any existing connection
if (m_socket.isOpen()) {
m_socket.close();
}
m_running = false;
disconnect(thread(), SIGNAL(finished()), this, SLOT(finished()));
}
void RemoteSourceWorker::errorOccurred(QAbstractSocket::SocketError socketError)
{
qWarning() << "RemoteSourceWorker::errorOccurred: " << socketError;
}
void RemoteSourceWorker::handleInputMessages()
@ -71,15 +103,12 @@ void RemoteSourceWorker::handleInputMessages()
{
if (MsgDataBind::match(*message))
{
QMutexLocker mutexLocker(&m_mutex);
MsgDataBind* notif = (MsgDataBind*) message;
qDebug("RemoteSourceWorker::handleInputMessages: MsgDataBind: %s:%d", qPrintable(notif->getAddress().toString()), notif->getPort());
if (m_socket)
{
disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
m_socket->bind(notif->getAddress(), notif->getPort());
connect(m_socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}
disconnect(&m_socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
m_socket.bind(notif->getAddress(), notif->getPort());
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}
}
}
@ -89,16 +118,30 @@ void RemoteSourceWorker::readPendingDatagrams()
RemoteSuperBlock superBlock;
qint64 size;
while (m_socket->hasPendingDatagrams())
while (m_socket.hasPendingDatagrams())
{
QHostAddress sender;
quint16 senderPort = 0;
//qint64 pendingDataSize = m_socket->pendingDatagramSize();
size = m_socket->readDatagram((char *) &superBlock, (long long int) sizeof(RemoteSuperBlock), &sender, &senderPort);
size = m_socket.readDatagram((char *) &superBlock, (long long int) sizeof(RemoteSuperBlock), &sender, &senderPort);
if (size == sizeof(RemoteSuperBlock))
{
unsigned int dataBlockIndex = superBlock.m_header.m_frameIndex % m_nbDataBlocks;
int blockIndex = superBlock.m_header.m_blockIndex;
if (blockIndex == 0) // first block with meta data
{
const RemoteMetaDataFEC *metaData = (const RemoteMetaDataFEC *) &superBlock.m_protectedBlock;
uint32_t sampleRate = metaData->m_sampleRate;
if (m_sampleRate != sampleRate)
{
qDebug("RemoteSourceWorker::readPendingDatagrams: sampleRate: %u", sampleRate);
m_socket.setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, getDataSocketBufferSize(sampleRate));
m_sampleRate = sampleRate;
}
}
// create the first block for this index
if (m_dataBlocks[dataBlockIndex] == 0) {
@ -145,3 +188,12 @@ void RemoteSourceWorker::readPendingDatagrams()
}
}
int RemoteSourceWorker::getDataSocketBufferSize(uint32_t inSampleRate)
{
// set a floor value at 24 kS/s
uint32_t samplerate = inSampleRate < 24000 ? 24000 : inSampleRate;
// 250 ms (1/4s) at current sample rate
int bufferSize = (samplerate * 2 * (SDR_RX_SAMP_SZ == 16 ? 2 : 4)) / 4;
qDebug("RemoteSourceWorker::getDataSocketBufferSize: %d bytes", bufferSize);
return bufferSize;
}

View File

@ -20,13 +20,13 @@
#include <QObject>
#include <QHostAddress>
#include <QUdpSocket>
#include "util/message.h"
#include "util/messagequeue.h"
class RemoteDataQueue;
class RemoteDataBlock;
class QUdpSocket;
class RemoteSourceWorker : public QObject {
Q_OBJECT
@ -57,7 +57,7 @@ public:
RemoteSourceWorker(RemoteDataQueue *dataQueue, QObject* parent = 0);
~RemoteSourceWorker();
void startWork();
bool startWork();
void stopWork();
void dataBind(const QString& address, uint16_t port);
@ -68,12 +68,19 @@ private:
RemoteDataQueue *m_dataQueue;
QHostAddress m_address;
QUdpSocket *m_socket;
QUdpSocket m_socket;
QMutex m_mutex;
static const uint32_t m_nbDataBlocks = 4; //!< number of data blocks in the ring buffer
static const uint32_t m_nbDataBlocks = 4; //!< number of data blocks in the ring buffer
RemoteDataBlock *m_dataBlocks[m_nbDataBlocks]; //!< ring buffer of data blocks indexed by frame affinity
uint32_t m_sampleRate; //!< current sample rate from meta data
static int getDataSocketBufferSize(uint32_t inSampleRate);
private slots:
void started();
void finished();
void errorOccurred(QAbstractSocket::SocketError socketError);
void handleInputMessages();
void readPendingDatagrams();
};

View File

@ -100,8 +100,6 @@ bool RemoteOutput::start()
m_lastQueueLength = -2; // set first value out of bounds
m_chunkSizeCorrection = 0;
m_remoteOutputWorker->setTxDelay(m_settings.m_txDelay);
mutexLocker.unlock();
//applySettings(m_generalSettings, m_settings, true);
qDebug("RemoteOutput::start: started");
@ -260,7 +258,6 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool forc
{
QMutexLocker mutexLocker(&m_mutex);
bool forwardChange = false;
bool changeTxDelay = false;
QList<QString> reverseAPIKeys;
if ((m_settings.m_dataAddress != settings.m_dataAddress) || force) {
@ -295,7 +292,6 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool forc
m_tickMultiplier = m_tickMultiplier < 20 ? 20 : m_tickMultiplier; // not below half a second
forwardChange = true;
changeTxDelay = true;
}
if (force || (m_settings.m_nbFECBlocks != settings.m_nbFECBlocks))
@ -305,28 +301,12 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool forc
if (m_remoteOutputWorker != 0) {
m_remoteOutputWorker->setNbBlocksFEC(settings.m_nbFECBlocks);
}
changeTxDelay = true;
}
if (force || (m_settings.m_txDelay != settings.m_txDelay))
{
reverseAPIKeys.append("txDelay");
changeTxDelay = true;
}
if (changeTxDelay)
{
if (m_remoteOutputWorker != 0) {
m_remoteOutputWorker->setTxDelay(settings.m_txDelay);
}
}
mutexLocker.unlock();
qDebug() << "RemoteOutput::applySettings:"
<< " m_sampleRate: " << settings.m_sampleRate
<< " m_txDelay: " << settings.m_txDelay
<< " m_nbFECBlocks: " << settings.m_nbFECBlocks
<< " m_apiAddress: " << settings.m_apiAddress
<< " m_apiPort: " << settings.m_apiPort
@ -421,9 +401,6 @@ void RemoteOutput::webapiUpdateDeviceSettings(
if (deviceSettingsKeys.contains("sampleRate")) {
settings.m_sampleRate = response.getRemoteOutputSettings()->getSampleRate();
}
if (deviceSettingsKeys.contains("txDelay")) {
settings.m_txDelay = response.getRemoteOutputSettings()->getTxDelay();
}
if (deviceSettingsKeys.contains("nbFECBlocks")) {
settings.m_nbFECBlocks = response.getRemoteOutputSettings()->getNbFecBlocks();
}
@ -474,7 +451,6 @@ void RemoteOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re
{
response.getRemoteOutputSettings()->setCenterFrequency(settings.m_centerFrequency);
response.getRemoteOutputSettings()->setSampleRate(settings.m_sampleRate);
response.getRemoteOutputSettings()->setTxDelay(settings.m_txDelay);
response.getRemoteOutputSettings()->setNbFecBlocks(settings.m_nbFECBlocks);
response.getRemoteOutputSettings()->setApiAddress(new QString(settings.m_apiAddress));
response.getRemoteOutputSettings()->setApiPort(settings.m_apiPort);
@ -659,9 +635,6 @@ void RemoteOutput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys,
if (deviceSettingsKeys.contains("sampleRate") || force) {
swgRemoteOutputSettings->setSampleRate(settings.m_sampleRate);
}
if (deviceSettingsKeys.contains("txDelay") || force) {
swgRemoteOutputSettings->setTxDelay(settings.m_txDelay);
}
if (deviceSettingsKeys.contains("nbFECBlocks") || force) {
swgRemoteOutputSettings->setNbFecBlocks(settings.m_nbFECBlocks);
}

View File

@ -211,20 +211,11 @@ void RemoteOutputSinkGui::updateSampleRate()
ui->deviceRateText->setText(tr("%1k").arg((float)(m_sampleRate) / 1000));
}
void RemoteOutputSinkGui::updateTxDelayTooltip()
{
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 RemoteOutputSinkGui::displaySettings()
{
blockApplySettings(true);
ui->centerFrequency->setValue(m_deviceCenterFrequency / 1000);
ui->sampleRate->setValue(m_settings.m_sampleRate);
ui->txDelay->setValue(m_settings.m_txDelay*100);
ui->txDelayText->setText(tr("%1").arg(m_settings.m_txDelay*100));
ui->nbFECBlocks->setValue(m_settings.m_nbFECBlocks);
QString s0 = QString::number(128 + m_settings.m_nbFECBlocks, 'f', 0);
@ -288,15 +279,6 @@ void RemoteOutputSinkGui::updateStatus()
void RemoteOutputSinkGui::on_sampleRate_changed(quint64 value)
{
m_settings.m_sampleRate = value;
updateTxDelayTooltip();
sendSettings();
}
void RemoteOutputSinkGui::on_txDelay_valueChanged(int value)
{
m_settings.m_txDelay = value / 100.0;
ui->txDelayText->setText(tr("%1").arg(value));
updateTxDelayTooltip();
sendSettings();
}
@ -308,7 +290,6 @@ void RemoteOutputSinkGui::on_nbFECBlocks_valueChanged(int value)
QString s = QString::number(nbOriginalBlocks + nbFECBlocks, 'f', 0);
QString s1 = QString::number(nbFECBlocks, 'f', 0);
ui->nominalNbBlocksText->setText(tr("%1/%2").arg(s).arg(s1));
updateTxDelayTooltip();
sendSettings();
}

View File

@ -124,7 +124,6 @@ private:
void sendControl(bool force = false);
void sendSettings();
void updateSampleRate();
void updateTxDelayTooltip();
void displayEventCounts();
void displayEventStatus(int recoverableCount, int unrecoverableCount);
void displayEventTimer();
@ -134,7 +133,6 @@ private:
private slots:
void handleInputMessages();
void on_sampleRate_changed(quint64 value);
void on_txDelay_valueChanged(int value);
void on_nbFECBlocks_valueChanged(int value);
void on_deviceIndex_returnPressed();
void on_channelIndex_returnPressed();

View File

@ -249,60 +249,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="txDelayLabel">
<property name="text">
<string>UDly</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="txDelay">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Delay between consecutive UDP packets in percentage of nominal UDP packet process time</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>90</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="txDelayText">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>90</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">

View File

@ -22,8 +22,6 @@
///////////////////////////////////////////////////////////////////////////////////
#include <thread>
#include <chrono>
#include <boost/crc.hpp>
#include <boost/cstdint.hpp>
@ -93,7 +91,6 @@ void RemoteOutputSender::sendDataBlock(RemoteDataBlock *dataBlock)
uint16_t frameIndex = dataBlock->m_txControlBlock.m_frameIndex;
int nbBlocksFEC = dataBlock->m_txControlBlock.m_nbBlocksFEC;
int txDelay = dataBlock->m_txControlBlock.m_txDelay;
m_remoteHostAddress.setAddress(dataBlock->m_txControlBlock.m_dataAddress);
uint16_t dataPort = dataBlock->m_txControlBlock.m_dataPort;
RemoteSuperBlock *txBlockx = dataBlock->m_superBlocks;
@ -102,11 +99,8 @@ void RemoteOutputSender::sendDataBlock(RemoteDataBlock *dataBlock)
{
if (m_udpSocket)
{
for (int i = 0; i < RemoteNbOrginalBlocks; i++)
{
// send block via UDP
for (int i = 0; i < RemoteNbOrginalBlocks; i++) { // send block via UDP
m_udpSocket->writeDatagram((const char*)&txBlockx[i], (qint64 ) RemoteUdpSize, m_remoteHostAddress, dataPort);
std::this_thread::sleep_for(std::chrono::microseconds(txDelay));
}
}
}
@ -152,11 +146,8 @@ void RemoteOutputSender::sendDataBlock(RemoteDataBlock *dataBlock)
// Transmit all blocks
if (m_udpSocket)
{
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++)
{
// send block via UDP
for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++) { // send block via UDP
m_udpSocket->writeDatagram((const char*)&txBlockx[i], (qint64 ) RemoteUdpSize, m_remoteHostAddress, dataPort);
std::this_thread::sleep_for(std::chrono::microseconds(txDelay));
}
}
}

View File

@ -27,7 +27,6 @@ void RemoteOutputSettings::resetToDefaults()
{
m_centerFrequency = 435000*1000;
m_sampleRate = 48000;
m_txDelay = 0.35;
m_nbFECBlocks = 0;
m_apiAddress = "127.0.0.1";
m_apiPort = 9091;
@ -47,7 +46,6 @@ QByteArray RemoteOutputSettings::serialize() const
s.writeU64(1, m_centerFrequency);
s.writeU32(2, m_sampleRate);
s.writeFloat(3, m_txDelay);
s.writeU32(4, m_nbFECBlocks);
s.writeString(5, m_apiAddress);
s.writeU32(6, m_apiPort);
@ -79,7 +77,6 @@ bool RemoteOutputSettings::deserialize(const QByteArray& data)
d.readU64(1, &m_centerFrequency, 435000*1000);
d.readU32(2, &m_sampleRate, 48000);
d.readFloat(3, &m_txDelay, 0.5);
d.readU32(4, &m_nbFECBlocks, 0);
d.readString(5, &m_apiAddress, "127.0.0.1");
d.readU32(6, &uintval, 9090);

View File

@ -24,7 +24,6 @@
struct RemoteOutputSettings {
quint64 m_centerFrequency;
quint32 m_sampleRate;
float m_txDelay;
quint32 m_nbFECBlocks;
QString m_apiAddress;
quint16 m_apiPort;

View File

@ -49,7 +49,6 @@ public:
void setSamplerate(int samplerate);
void setNbBlocksFEC(uint32_t nbBlocksFEC) { m_udpSinkFEC.setNbBlocksFEC(nbBlocksFEC); };
void setTxDelay(float txDelay) { m_udpSinkFEC.setTxDelay(txDelay); };
void setDataAddress(const QString& address, uint16_t port) { m_udpSinkFEC.setRemoteAddress(address, port); }
bool isRunning() const { return m_running; }

View File

@ -32,7 +32,6 @@ UDPSinkFEC::UDPSinkFEC() :
m_nbSamples(0),
m_nbBlocksFEC(0),
m_txDelayRatio(0.0),
m_txDelay(0),
m_dataBlock(nullptr),
m_txBlockIndex(0),
m_txBlocksIndex(0),
@ -71,35 +70,16 @@ void UDPSinkFEC::stopSender()
m_senderThread->wait();
}
void UDPSinkFEC::setTxDelay(float txDelayRatio)
{
// delay is calculated from the fraction of the nominal UDP block process time
// frame size: 127 * (126 or 63 samples depending on I or Q sample bytes of 2 or 4 bytes respectively)
// 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 = RemoteNbBytesPerBlock / sizeof(Sample);
double delay = m_sampleRate == 0 ? 1.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate;
delay /= 128 + m_nbBlocksFEC;
m_txDelay = delay * 1e6;
qDebug() << "UDPSinkFEC::setTxDelay:"
<< "txDelay:" << txDelayRatio
<< "m_txDelay:" << m_txDelay << " us"
<< "m_sampleRate:" << m_sampleRate;
}
void UDPSinkFEC::setNbBlocksFEC(uint32_t nbBlocksFEC)
{
qDebug() << "UDPSinkFEC::setNbBlocksFEC: nbBlocksFEC: " << nbBlocksFEC;
m_nbBlocksFEC = nbBlocksFEC;
setTxDelay(m_txDelayRatio);
}
void UDPSinkFEC::setSampleRate(uint32_t sampleRate)
{
qDebug() << "UDPSinkFEC::setSampleRate: sampleRate: " << sampleRate;
m_sampleRate = sampleRate;
setTxDelay(m_txDelayRatio);
}
void UDPSinkFEC::setRemoteAddress(const QString& address, uint16_t port)
@ -200,7 +180,6 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
m_dataBlock->m_txControlBlock.m_processed = false;
m_dataBlock->m_txControlBlock.m_complete = true;
m_dataBlock->m_txControlBlock.m_nbBlocksFEC = m_nbBlocksFEC;
m_dataBlock->m_txControlBlock.m_txDelay = m_txDelay;
m_dataBlock->m_txControlBlock.m_dataAddress = m_remoteAddress;
m_dataBlock->m_txControlBlock.m_dataPort = m_remotePort;

View File

@ -67,7 +67,6 @@ public:
void setSampleRate(uint32_t sampleRate);
void setNbBlocksFEC(uint32_t nbBlocksFEC);
void setTxDelay(float txDelayRatio);
void setRemoteAddress(const QString& address, uint16_t port);
/** Return true if the stream is OK, return false if there is an error. */
@ -87,7 +86,6 @@ private:
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
RemoteDataBlock *m_dataBlock;
RemoteSuperBlock m_superBlock; //!< current super block being built
int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row

View File

@ -68,8 +68,7 @@ LocalInputGui::LocalInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
m_countUnrecoverable(0),
m_countRecovered(0),
m_doApplySettings(true),
m_forceSettings(true),
m_txDelay(0.0)
m_forceSettings(true)
{
m_paletteGreenText.setColor(QPalette::WindowText, Qt::green);
m_paletteWhiteText.setColor(QPalette::WindowText, Qt::white);

View File

@ -92,7 +92,6 @@ private:
bool m_doApplySettings;
bool m_forceSettings;
double m_txDelay;
QPalette m_paletteGreenText;
QPalette m_paletteWhiteText;

View File

@ -68,8 +68,7 @@ RemoteInputGui::RemoteInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
m_countUnrecoverable(0),
m_countRecovered(0),
m_doApplySettings(true),
m_forceSettings(true),
m_txDelay(0.0)
m_forceSettings(true)
{
m_paletteGreenText.setColor(QPalette::WindowText, Qt::green);
m_paletteWhiteText.setColor(QPalette::WindowText, Qt::white);

View File

@ -94,7 +94,6 @@ private:
bool m_doApplySettings;
bool m_forceSettings;
double m_txDelay;
QPalette m_paletteGreenText;
QPalette m_paletteWhiteText;

View File

@ -177,7 +177,6 @@ Example of a JSON file (delay is an example you normally do not need it):
"reverseAPIPort": 8888,
"rgbColor": -7601148,
"title": "Channel 0",
"txDelay": 0,
"useReverseAPI": 0
},
"channelType": "RemoteSink",

View File

@ -126,16 +126,15 @@ struct RemoteTxControlBlock
bool m_processed;
uint16_t m_frameIndex;
int m_nbBlocksFEC;
int m_txDelay;
QString m_dataAddress;
uint16_t m_dataPort;
RemoteTxControlBlock() {
RemoteTxControlBlock()
{
m_complete = false;
m_processed = false;
m_frameIndex = 0;
m_nbBlocksFEC = 0;
m_txDelay = 100;
m_dataAddress = "127.0.0.1";
m_dataPort = 9090;
}

View File

@ -9841,11 +9841,6 @@ margin-bottom: 20px;
"sampleRate" : {
"type" : "integer"
},
"txDelay" : {
"type" : "number",
"format" : "float",
"description" : "minimum delay in ms between two consecutive packets sending"
},
"nbFECBlocks" : {
"type" : "integer"
},
@ -51601,7 +51596,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2021-12-04T20:19:18.225+01:00
Generated 2021-12-07T06:38:29.681+01:00
</div>
</div>
</div>

View File

@ -6,10 +6,6 @@ RemoteOutputSettings:
format: int64
sampleRate:
type: integer
txDelay:
description: minimum delay in ms between two consecutive packets sending
type: number
format: float
nbFECBlocks:
type: integer
apiAddress:

View File

@ -6,10 +6,6 @@ RemoteOutputSettings:
format: int64
sampleRate:
type: integer
txDelay:
description: minimum delay in ms between two consecutive packets sending
type: number
format: float
nbFECBlocks:
type: integer
apiAddress:

View File

@ -9841,11 +9841,6 @@ margin-bottom: 20px;
"sampleRate" : {
"type" : "integer"
},
"txDelay" : {
"type" : "number",
"format" : "float",
"description" : "minimum delay in ms between two consecutive packets sending"
},
"nbFECBlocks" : {
"type" : "integer"
},
@ -51601,7 +51596,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2021-12-04T20:19:18.225+01:00
Generated 2021-12-07T06:38:29.681+01:00
</div>
</div>
</div>

View File

@ -32,8 +32,6 @@ SWGRemoteOutputSettings::SWGRemoteOutputSettings() {
m_center_frequency_isSet = false;
sample_rate = 0;
m_sample_rate_isSet = false;
tx_delay = 0.0f;
m_tx_delay_isSet = false;
nb_fec_blocks = 0;
m_nb_fec_blocks_isSet = false;
api_address = nullptr;
@ -68,8 +66,6 @@ SWGRemoteOutputSettings::init() {
m_center_frequency_isSet = false;
sample_rate = 0;
m_sample_rate_isSet = false;
tx_delay = 0.0f;
m_tx_delay_isSet = false;
nb_fec_blocks = 0;
m_nb_fec_blocks_isSet = false;
api_address = new QString("");
@ -99,7 +95,6 @@ SWGRemoteOutputSettings::cleanup() {
if(api_address != nullptr) {
delete api_address;
}
@ -133,8 +128,6 @@ SWGRemoteOutputSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&sample_rate, pJson["sampleRate"], "qint32", "");
::SWGSDRangel::setValue(&tx_delay, pJson["txDelay"], "float", "");
::SWGSDRangel::setValue(&nb_fec_blocks, pJson["nbFECBlocks"], "qint32", "");
::SWGSDRangel::setValue(&api_address, pJson["apiAddress"], "QString", "QString");
@ -179,9 +172,6 @@ SWGRemoteOutputSettings::asJsonObject() {
if(m_sample_rate_isSet){
obj->insert("sampleRate", QJsonValue(sample_rate));
}
if(m_tx_delay_isSet){
obj->insert("txDelay", QJsonValue(tx_delay));
}
if(m_nb_fec_blocks_isSet){
obj->insert("nbFECBlocks", QJsonValue(nb_fec_blocks));
}
@ -239,16 +229,6 @@ SWGRemoteOutputSettings::setSampleRate(qint32 sample_rate) {
this->m_sample_rate_isSet = true;
}
float
SWGRemoteOutputSettings::getTxDelay() {
return tx_delay;
}
void
SWGRemoteOutputSettings::setTxDelay(float tx_delay) {
this->tx_delay = tx_delay;
this->m_tx_delay_isSet = true;
}
qint32
SWGRemoteOutputSettings::getNbFecBlocks() {
return nb_fec_blocks;
@ -370,9 +350,6 @@ SWGRemoteOutputSettings::isSet(){
if(m_sample_rate_isSet){
isObjectUpdated = true; break;
}
if(m_tx_delay_isSet){
isObjectUpdated = true; break;
}
if(m_nb_fec_blocks_isSet){
isObjectUpdated = true; break;
}

View File

@ -48,9 +48,6 @@ public:
qint32 getSampleRate();
void setSampleRate(qint32 sample_rate);
float getTxDelay();
void setTxDelay(float tx_delay);
qint32 getNbFecBlocks();
void setNbFecBlocks(qint32 nb_fec_blocks);
@ -94,9 +91,6 @@ private:
qint32 sample_rate;
bool m_sample_rate_isSet;
float tx_delay;
bool m_tx_delay_isSet;
qint32 nb_fec_blocks;
bool m_nb_fec_blocks_isSet;

View File

@ -53,7 +53,6 @@ def getInputOptions():
parser.add_option("--rmt-address", dest="remote_address", help="RemoteSink: destination data address", metavar="IP_ADDRESS", type="string")
parser.add_option("--rmt-port", dest="remote_port", help="RemoteSink: destination data port", metavar="PORT", type="int")
parser.add_option("--rmt-fec", dest="remote_fec", help="RemoteSink: number of FEC blocks per frame", metavar="NUMBER", type="int")
parser.add_option("--rmt-txdelay", dest="remote_tx_delay", help="RemoteSink: inter block UDP Tx delay percentage", metavar="PERCENT", type="int")
(options, args) = parser.parse_args()
@ -326,8 +325,6 @@ def setupChannel(deviceset_url, options):
settings["RemoteSinkSettings"]["dataPort"] = options.remote_port
if options.remote_fec:
settings["RemoteSinkSettings"]["nbFECBlocks"] = options.remote_fec
if options.remote_tx_delay:
settings["RemoteSinkSettings"]["txDelay"] = options.remote_tx_delay
r = callAPI(deviceset_url + "/channel/%d/settings" % i, "PATCH", None, settings, "Change demod")
if r is None:

View File

@ -63,7 +63,6 @@
"reverseAPIPort": 8888,
"rgbColor": -7601148,
"title": "Channel 0",
"txDelay": 0,
"useReverseAPI": 0
},
"channelType": "RemoteSink",
@ -98,7 +97,6 @@
"reverseAPIPort": 8888,
"rgbColor": -7601148,
"title": "Remote sink",
"txDelay": 0,
"useReverseAPI": 0
},
"channelType": "RemoteSink",
@ -133,7 +131,6 @@
"reverseAPIPort": 8888,
"rgbColor": -7601148,
"title": "Remote sink",
"txDelay": 0,
"useReverseAPI": 0
},
"channelType": "RemoteSink",
@ -148,4 +145,4 @@
null,
"Start device on deviceset R0"
]
]
]