1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-07-31 13:02:27 -04:00

SDRDaemonSink: calculate Tx delay in UDP sink

This commit is contained in:
f4exb 2018-09-11 01:01:43 +02:00
parent 9bf030c824
commit 6aff1a3db3
5 changed files with 30 additions and 23 deletions

View File

@ -38,6 +38,7 @@
#include "device/devicesinkapi.h" #include "device/devicesinkapi.h"
#include "device/deviceuiset.h" #include "device/deviceuiset.h"
#include "udpsinkfec.h"
#include "sdrdaemonsinkgui.h" #include "sdrdaemonsinkgui.h"
SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent) : SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
@ -214,7 +215,8 @@ void SDRdaemonSinkGui::updateSampleRate()
void SDRdaemonSinkGui::updateTxDelayTooltip() void SDRdaemonSinkGui::updateTxDelayTooltip()
{ {
double delay = ((127*126*m_settings.m_txDelay) / m_settings.m_sampleRate)/(128 + m_settings.m_nbFECBlocks); int samplesPerBlock = UDPSinkFEC::bytesPerBlock / (SDR_TX_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))); ui->txDelayText->setToolTip(tr("%1 us").arg(QString::number(delay*1e6, 'f', 0)));
} }

View File

@ -98,8 +98,7 @@ bool SDRdaemonSinkOutput::start()
m_lastQueueLength = -2; // set first value out of bounds m_lastQueueLength = -2; // set first value out of bounds
m_chunkSizeCorrection = 0; m_chunkSizeCorrection = 0;
double delay = ((127*126*m_settings.m_txDelay) / m_settings.m_sampleRate)/(128 + m_settings.m_nbFECBlocks); m_sdrDaemonSinkThread->setTxDelay(m_settings.m_txDelay);
m_sdrDaemonSinkThread->setTxDelay((int) (delay*1e6));
mutexLocker.unlock(); mutexLocker.unlock();
//applySettings(m_generalSettings, m_settings, true); //applySettings(m_generalSettings, m_settings, true);
@ -280,16 +279,8 @@ void SDRdaemonSinkOutput::applySettings(const SDRdaemonSinkSettings& settings, b
if (changeTxDelay) if (changeTxDelay)
{ {
double delay = ((127*126*settings.m_txDelay) / settings.m_sampleRate)/(128 + settings.m_nbFECBlocks); if (m_sdrDaemonSinkThread != 0) {
qDebug("SDRdaemonSinkOutput::applySettings: Tx delay: %f us", delay*1e6); m_sdrDaemonSinkThread->setTxDelay(settings.m_txDelay);
if (m_sdrDaemonSinkThread != 0)
{
// delay is calculated as a fraction of the nominal UDP block process time
// frame size: 127 * 126 samples
// 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_sdrDaemonSinkThread->setTxDelay((int) (delay*1e6));
} }
} }

View File

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

View File

@ -33,6 +33,7 @@ UDPSinkFEC::UDPSinkFEC() :
m_sampleBits(SDR_TX_SAMP_SZ), m_sampleBits(SDR_TX_SAMP_SZ),
m_nbSamples(0), m_nbSamples(0),
m_nbBlocksFEC(0), m_nbBlocksFEC(0),
m_txDelayRatio(0.0),
m_txDelay(0), m_txDelay(0),
m_txBlockIndex(0), m_txBlockIndex(0),
m_txBlocksIndex(0), m_txBlocksIndex(0),
@ -66,16 +67,31 @@ UDPSinkFEC::~UDPSinkFEC()
delete m_udpThread; delete m_udpThread;
} }
void UDPSinkFEC::setTxDelay(uint32_t txDelay) void UDPSinkFEC::setTxDelay(float txDelayRatio)
{ {
qDebug() << "UDPSinkFEC::setTxDelay: txDelay: " << txDelay; // delay is calculated from the fraction of the nominal UDP block process time
m_txDelay = txDelay; // 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 = bytesPerBlock / (m_sampleBytes*2);
double delay = ((127*samplesPerBlock*txDelayRatio) / m_sampleRate)/(128 + m_nbBlocksFEC);
m_txDelay = delay * 1e6;
qDebug() << "UDPSinkFEC::setTxDelay: txDelay: " << txDelayRatio << " m_txDelay: " << m_txDelay << " us";
} }
void UDPSinkFEC::setNbBlocksFEC(uint32_t nbBlocksFEC) void UDPSinkFEC::setNbBlocksFEC(uint32_t nbBlocksFEC)
{ {
qDebug() << "UDPSinkFEC::setNbBlocksFEC: nbBlocksFEC: " << nbBlocksFEC; qDebug() << "UDPSinkFEC::setNbBlocksFEC: nbBlocksFEC: " << nbBlocksFEC;
m_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) void UDPSinkFEC::setRemoteAddress(const QString& address, uint16_t port)

View File

@ -110,14 +110,11 @@ public:
return ret; return ret;
} }
/** Set sample rate given in Hz */ /** Set sample rate given in S/s */
void setSampleRate(uint32_t sampleRate) { m_sampleRate = sampleRate; } void setSampleRate(uint32_t sampleRate);
void setSampleBytes(uint8_t sampleBytes) { m_sampleBytes = (sampleBytes & 0x0F) + (m_sampleBytes & 0xF0); }
void setSampleBits(uint8_t sampleBits) { m_sampleBits = sampleBits; }
void setNbBlocksFEC(uint32_t nbBlocksFEC); void setNbBlocksFEC(uint32_t nbBlocksFEC);
void setTxDelay(uint32_t txDelay); void setTxDelay(float txDelayRatio);
void setRemoteAddress(const QString& address, uint16_t port); void setRemoteAddress(const QString& address, uint16_t port);
/** Return true if the stream is OK, return false if there is an error. */ /** Return true if the stream is OK, return false if there is an error. */
@ -142,6 +139,7 @@ private:
MetaDataFEC m_currentMetaFEC; //!< Meta data for current frame MetaDataFEC m_currentMetaFEC; //!< Meta data for current frame
uint32_t m_nbBlocksFEC; //!< Variable number of FEC blocks uint32_t m_nbBlocksFEC; //!< Variable number of FEC blocks
float m_txDelayRatio; //!< Delay in ratio of nominal frame period
uint32_t m_txDelay; //!< Delay in microseconds (usleep) between each sending of an UDP datagram uint32_t m_txDelay; //!< Delay in microseconds (usleep) between each sending of an UDP datagram
SuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC SuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC
SuperBlock m_superBlock; //!< current super block being built SuperBlock m_superBlock; //!< current super block being built