diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp index 08ac4ca32..d39d3b406 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp @@ -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))); } diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp index 03f4808cb..f47b42b48 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkoutput.cpp @@ -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); } } diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h index 39e40bb0c..e6a2fd91a 100644 --- a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h +++ b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkthread.h @@ -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; } diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp b/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp index 6fa7ee1d2..b8fd17009 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp @@ -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) diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfec.h b/plugins/samplesink/sdrdaemonsink/udpsinkfec.h index a1cae77f5..f613fb7ed 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfec.h +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfec.h @@ -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