1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-02-03 09:44:01 -05: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/deviceuiset.h"
#include "udpsinkfec.h"
#include "sdrdaemonsinkgui.h"
SDRdaemonSinkGui::SDRdaemonSinkGui(DeviceUISet *deviceUISet, QWidget* parent) :
@ -214,7 +215,8 @@ void SDRdaemonSinkGui::updateSampleRate()
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)));
}

View File

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

View File

@ -50,7 +50,7 @@ public:
void setSamplerate(int samplerate);
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); }
bool isRunning() const { return m_running; }

View File

@ -33,6 +33,7 @@ UDPSinkFEC::UDPSinkFEC() :
m_sampleBits(SDR_TX_SAMP_SZ),
m_nbSamples(0),
m_nbBlocksFEC(0),
m_txDelayRatio(0.0),
m_txDelay(0),
m_txBlockIndex(0),
m_txBlocksIndex(0),
@ -66,16 +67,31 @@ UDPSinkFEC::~UDPSinkFEC()
delete m_udpThread;
}
void UDPSinkFEC::setTxDelay(uint32_t txDelay)
void UDPSinkFEC::setTxDelay(float txDelayRatio)
{
qDebug() << "UDPSinkFEC::setTxDelay: txDelay: " << txDelay;
m_txDelay = txDelay;
// 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 = 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)
{
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)

View File

@ -110,14 +110,11 @@ public:
return ret;
}
/** Set sample rate given in Hz */
void setSampleRate(uint32_t sampleRate) { m_sampleRate = sampleRate; }
void setSampleBytes(uint8_t sampleBytes) { m_sampleBytes = (sampleBytes & 0x0F) + (m_sampleBytes & 0xF0); }
void setSampleBits(uint8_t sampleBits) { m_sampleBits = sampleBits; }
/** Set sample rate given in S/s */
void setSampleRate(uint32_t sampleRate);
void setNbBlocksFEC(uint32_t nbBlocksFEC);
void setTxDelay(uint32_t txDelay);
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. */
@ -142,6 +139,7 @@ private:
MetaDataFEC 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
SuperBlock m_txBlocks[4][256]; //!< UDP blocks to send with original data + FEC
SuperBlock m_superBlock; //!< current super block being built