From 5e588ae09eacfd005bf019516492e2dbae45f404 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 13 Sep 2018 00:31:49 +0200 Subject: [PATCH] SDRDaemon: cleanup on UDP Tx side to use sdrdaemondatablock.h definitions and Rx sample size --- plugins/channelrx/daemonsink/daemonsink.cpp | 9 +- plugins/channelrx/daemonsink/daemonsink.h | 1 - .../channelrx/daemonsink/daemonsinkthread.cpp | 2 + .../channelrx/daemonsink/daemonsinkthread.h | 1 + .../sdrdaemonsink/sdrdaemonsinkgui.cpp | 3 +- .../samplesink/sdrdaemonsink/udpsinkfec.cpp | 112 +++++---------- plugins/samplesink/sdrdaemonsink/udpsinkfec.h | 127 +++++++++--------- sdrbase/channel/sdrdaemondatablock.h | 8 +- 8 files changed, 114 insertions(+), 149 deletions(-) diff --git a/plugins/channelrx/daemonsink/daemonsink.cpp b/plugins/channelrx/daemonsink/daemonsink.cpp index 2b69618dc..ac5dfd02e 100644 --- a/plugins/channelrx/daemonsink/daemonsink.cpp +++ b/plugins/channelrx/daemonsink/daemonsink.cpp @@ -52,7 +52,6 @@ DaemonSink::DaemonSink(DeviceSourceAPI *deviceAPI) : m_dataBlock(0), m_centerFrequency(0), m_sampleRate(48000), - m_sampleBytes(SDR_RX_SAMP_SZ <= 16 ? 2 : 4), m_nbBlocksFEC(0), m_txDelay(35), m_dataAddress("127.0.0.1"), @@ -115,7 +114,7 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec metaData.m_centerFrequency = m_centerFrequency; metaData.m_sampleRate = m_sampleRate; - metaData.m_sampleBytes = m_sampleBytes & 0xF; + metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); metaData.m_sampleBits = SDR_RX_SAMP_SZ; metaData.m_nbOriginalBlocks = SDRDaemonNbOrginalBlocks; metaData.m_nbFECBlocks = m_nbBlocksFEC; @@ -133,6 +132,8 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec 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; memcpy((void *) &superBlock.m_protectedBlock, (const void *) &metaData, sizeof(SDRDaemonMetaDataFEC)); if (!(metaData == m_currentMetaFEC)) @@ -154,7 +155,7 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec } // block zero // handle different sample sizes... - int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); + int samplesPerBlock = SDRDaemonNbBytesPerBlock / (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)], @@ -173,6 +174,8 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec m_superBlock.m_header.m_frameIndex = m_frameCount; m_superBlock.m_header.m_blockIndex = m_txBlockIndex; + m_superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); + 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 diff --git a/plugins/channelrx/daemonsink/daemonsink.h b/plugins/channelrx/daemonsink/daemonsink.h index fcadb413a..b50986c48 100644 --- a/plugins/channelrx/daemonsink/daemonsink.h +++ b/plugins/channelrx/daemonsink/daemonsink.h @@ -144,7 +144,6 @@ private: uint64_t m_centerFrequency; uint32_t m_sampleRate; - uint8_t m_sampleBytes; int m_nbBlocksFEC; int m_txDelay; QString m_dataAddress; diff --git a/plugins/channelrx/daemonsink/daemonsinkthread.cpp b/plugins/channelrx/daemonsink/daemonsinkthread.cpp index 423e17454..ba0cc1ab8 100644 --- a/plugins/channelrx/daemonsink/daemonsinkthread.cpp +++ b/plugins/channelrx/daemonsink/daemonsinkthread.cpp @@ -132,6 +132,8 @@ void DaemonSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock) txBlockx[i].m_header.m_frameIndex = frameIndex; txBlockx[i].m_header.m_blockIndex = i; + txBlockx[i].m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); + txBlockx[i].m_header.m_sampleBits = SDR_RX_SAMP_SZ; descriptorBlocks[i].Block = (void *) &(txBlockx[i].m_protectedBlock); descriptorBlocks[i].Index = txBlockx[i].m_header.m_blockIndex; } diff --git a/plugins/channelrx/daemonsink/daemonsinkthread.h b/plugins/channelrx/daemonsink/daemonsinkthread.h index 5e468f7a9..e87f31ce8 100644 --- a/plugins/channelrx/daemonsink/daemonsinkthread.h +++ b/plugins/channelrx/daemonsink/daemonsinkthread.h @@ -69,6 +69,7 @@ private: QMutex m_startWaitMutex; QWaitCondition m_startWaiter; bool m_running; + uint8_t m_sampleBytes; CM256 m_cm256; CM256 *m_cm256p; diff --git a/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp b/plugins/samplesink/sdrdaemonsink/sdrdaemonsinkgui.cpp index d39d3b406..c2607530f 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 "channel/sdrdaemondatablock.h" #include "udpsinkfec.h" #include "sdrdaemonsinkgui.h" @@ -215,7 +216,7 @@ void SDRdaemonSinkGui::updateSampleRate() void SDRdaemonSinkGui::updateTxDelayTooltip() { - int samplesPerBlock = UDPSinkFEC::bytesPerBlock / (SDR_TX_SAMP_SZ <= 16 ? 4 : 8); + int samplesPerBlock = SDRDaemonNbBytesPerBlock / (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))); } diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp b/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp index b8fd17009..77984afe2 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfec.cpp @@ -29,8 +29,6 @@ MESSAGE_CLASS_DEFINITION(UDPSinkFECWorker::MsgConfigureRemoteAddress, Message) UDPSinkFEC::UDPSinkFEC() : m_sampleRate(48000), - m_sampleBytes(SDR_TX_SAMP_SZ <= 16 ? 2 : 4), - m_sampleBits(SDR_TX_SAMP_SZ), m_nbSamples(0), m_nbBlocksFEC(0), m_txDelayRatio(0.0), @@ -40,8 +38,8 @@ UDPSinkFEC::UDPSinkFEC() : m_frameCount(0), m_sampleIndex(0) { - memset((char *) m_txBlocks, 0, 4*256*sizeof(SuperBlock)); - memset((char *) &m_superBlock, 0, sizeof(SuperBlock)); + memset((char *) m_txBlocks, 0, 4*256*sizeof(SDRDaemonSuperBlock)); + memset((char *) &m_superBlock, 0, sizeof(SDRDaemonSuperBlock)); m_currentMetaFEC.init(); m_bufMeta = new uint8_t[m_udpSize]; m_buf = new uint8_t[m_udpSize]; @@ -74,7 +72,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 = bytesPerBlock / (m_sampleBytes*2); + int samplesPerBlock = SDRDaemonNbBytesPerBlock / (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"; @@ -113,14 +111,14 @@ 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 { struct timeval tv; - MetaDataFEC metaData; + SDRDaemonMetaDataFEC metaData; gettimeofday(&tv, 0); metaData.m_centerFrequency = 0; // frequency not set by stream metaData.m_sampleRate = m_sampleRate; - metaData.m_sampleBytes = m_sampleBytes & 0xF; - metaData.m_sampleBits = m_sampleBits; + metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); + metaData.m_sampleBits = SDR_RX_SAMP_SZ; metaData.m_nbOriginalBlocks = m_nbOriginalBlocks; metaData.m_nbFECBlocks = m_nbBlocksFEC; metaData.m_tv_sec = tv.tv_sec; @@ -133,9 +131,11 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk memset((char *) &m_superBlock, 0, sizeof(m_superBlock)); - m_superBlock.header.frameIndex = m_frameCount; - m_superBlock.header.blockIndex = m_txBlockIndex; - memcpy((char *) &m_superBlock.protectedBlock, (const char *) &metaData, sizeof(MetaDataFEC)); + m_superBlock.m_header.m_frameIndex = m_frameCount; + m_superBlock.m_header.m_blockIndex = m_txBlockIndex; + m_superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); + m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; + memcpy((char *) &m_superBlock.m_protectedBlock, (const char *) &metaData, sizeof(SDRDaemonMetaDataFEC)); if (!(metaData == m_currentMetaFEC)) { @@ -157,74 +157,28 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk m_txBlockIndex = 1; // next Tx block with data } - int samplesPerBlock = bytesPerBlock / (m_sampleBytes*2); + int samplesPerBlock = SDRDaemonNbBytesPerBlock / (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 { - if (sizeof(Sample) == m_sampleBytes*2) // can do direct copy if sample sizes are equal - { - memcpy((char *) &m_superBlock.protectedBlock.m_buf[m_sampleIndex*m_sampleBytes*2], - (const char *) &(*it), - inRemainingSamples * sizeof(Sample)); - } - else if ((sizeof(Sample) == 8) && (m_sampleBytes == 2)) // modulators produce 16 bit samples - { - for (int is = 0; is < inRemainingSamples; is++) - { - int16_t *rp = (int16_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2]); - int16_t *ip = (int16_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2+2]); - *rp = (it+is)->m_real & 0xFFFF; - *ip = (it+is)->m_imag & 0xFFFF; - } - } - else if ((sizeof(Sample) == 4) && (m_sampleBytes == 4)) // use 16 bit samples for Tx - { - for (int is = 0; is < inRemainingSamples; is++) - { - int32_t *rp = (int32_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2]); - int32_t *ip = (int32_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2+4]); - *rp = (it+is)->m_real; - *ip = (it+is)->m_imag; - } - } - + memcpy((char *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], + (const char *) &(*it), + inRemainingSamples * sizeof(Sample)); m_sampleIndex += inRemainingSamples; it = end; // all input samples are consumed } else // complete super block and initiate the next if not end of frame { - if (sizeof(Sample) == m_sampleBytes*2) // can do direct copy if sample sizes are equal - { - memcpy((char *) &m_superBlock.protectedBlock.m_buf[m_sampleIndex*m_sampleBytes*2], - (const char *) &(*it), - (samplesPerBlock - m_sampleIndex) * sizeof(Sample)); - } - else if ((sizeof(Sample) == 8) && (m_sampleBytes == 2)) // modulators produce 16 bit samples - { - for (int is = 0; is < samplesPerBlock - m_sampleIndex; is++) - { - int16_t *rp = (int16_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2]); - int16_t *ip = (int16_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2+2]); - *rp = (it+is)->m_real & 0xFFFF; - *ip = (it+is)->m_imag & 0xFFFF; - } - } - else if ((sizeof(Sample) == 4) && (m_sampleBytes == 4)) // use 16 bit samples for Tx - { - for (int is = 0; is < samplesPerBlock - m_sampleIndex; is++) - { - int32_t *rp = (int32_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2]); - int32_t *ip = (int32_t*) &(m_superBlock.protectedBlock.m_buf[(m_sampleIndex+is)*m_sampleBytes*2+4]); - *rp = (it+is)->m_real; - *ip = (it+is)->m_imag; - } - } - + memcpy((char *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], + (const char *) &(*it), + (samplesPerBlock - m_sampleIndex) * sizeof(Sample)); it += samplesPerBlock - m_sampleIndex; m_sampleIndex = 0; - m_superBlock.header.frameIndex = m_frameCount; - m_superBlock.header.blockIndex = m_txBlockIndex; + m_superBlock.m_header.m_frameIndex = m_frameCount; + m_superBlock.m_header.m_blockIndex = m_txBlockIndex; + m_superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); + m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; m_txBlocks[m_txBlocksIndex][m_txBlockIndex] = m_superBlock; if (m_txBlockIndex == m_nbOriginalBlocks - 1) // frame complete @@ -263,7 +217,7 @@ UDPSinkFECWorker::~UDPSinkFECWorker() m_inputMessageQueue.clear(); } -void UDPSinkFECWorker::pushTxFrame(UDPSinkFEC::SuperBlock *txBlocks, +void UDPSinkFECWorker::pushTxFrame(SDRDaemonSuperBlock *txBlocks, uint32_t nbBlocksFEC, uint32_t txDelay, uint16_t frameIndex) @@ -320,11 +274,11 @@ void UDPSinkFECWorker::handleInputMessages() } } -void UDPSinkFECWorker::encodeAndTransmit(UDPSinkFEC::SuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay) +void UDPSinkFECWorker::encodeAndTransmit(SDRDaemonSuperBlock *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 - UDPSinkFEC::ProtectedBlock fecBlocks[256]; //!< FEC data + SDRDaemonProtectedBlock fecBlocks[256]; //!< FEC data if ((nbBlocksFEC == 0) || !m_cm256Valid) { @@ -339,7 +293,7 @@ void UDPSinkFECWorker::encodeAndTransmit(UDPSinkFEC::SuperBlock *txBlockx, uint1 } else { - cm256Params.BlockBytes = sizeof(UDPSinkFEC::ProtectedBlock); + cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock); cm256Params.OriginalCount = UDPSinkFEC::m_nbOriginalBlocks; cm256Params.RecoveryCount = nbBlocksFEC; @@ -348,13 +302,15 @@ void UDPSinkFECWorker::encodeAndTransmit(UDPSinkFEC::SuperBlock *txBlockx, uint1 for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i) { if (i >= cm256Params.OriginalCount) { - memset((char *) &txBlockx[i].protectedBlock, 0, sizeof(UDPSinkFEC::ProtectedBlock)); + memset((char *) &txBlockx[i].m_protectedBlock, 0, sizeof(SDRDaemonProtectedBlock)); } - txBlockx[i].header.frameIndex = frameIndex; - txBlockx[i].header.blockIndex = i; - descriptorBlocks[i].Block = (void *) &(txBlockx[i].protectedBlock); - descriptorBlocks[i].Index = txBlockx[i].header.blockIndex; + txBlockx[i].m_header.m_frameIndex = frameIndex; + txBlockx[i].m_header.m_blockIndex = i; + txBlockx[i].m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); + txBlockx[i].m_header.m_sampleBits = SDR_RX_SAMP_SZ; + descriptorBlocks[i].Block = (void *) &(txBlockx[i].m_protectedBlock); + descriptorBlocks[i].Index = txBlockx[i].m_header.m_blockIndex; } // Encode FEC blocks @@ -367,7 +323,7 @@ void UDPSinkFECWorker::encodeAndTransmit(UDPSinkFEC::SuperBlock *txBlockx, uint1 // Merge FEC with data to transmit for (int i = 0; i < cm256Params.RecoveryCount; i++) { - txBlockx[i + cm256Params.OriginalCount].protectedBlock = fecBlocks[i]; + txBlockx[i + cm256Params.OriginalCount].m_protectedBlock = fecBlocks[i]; } // Transmit all blocks diff --git a/plugins/samplesink/sdrdaemonsink/udpsinkfec.h b/plugins/samplesink/sdrdaemonsink/udpsinkfec.h index f613fb7ed..172e07312 100644 --- a/plugins/samplesink/sdrdaemonsink/udpsinkfec.h +++ b/plugins/samplesink/sdrdaemonsink/udpsinkfec.h @@ -31,6 +31,7 @@ #include "util/CRC64.h" #include "util/messagequeue.h" #include "util/message.h" +#include "channel/sdrdaemondatablock.h" #include "UDPSocket.h" @@ -42,52 +43,52 @@ class UDPSinkFEC : public QObject public: static const uint32_t m_udpSize = 512; //!< Size of UDP block in number of bytes static const uint32_t m_nbOriginalBlocks = 128; //!< Number of original blocks in a protected block sequence -#pragma pack(push, 1) - struct MetaDataFEC - { - uint32_t m_centerFrequency; //!< 4 center frequency in kHz - uint32_t m_sampleRate; //!< 8 sample rate in Hz - uint8_t m_sampleBytes; //!< 9 MSB(4): indicators, LSB(4) number of bytes per sample - uint8_t m_sampleBits; //!< 10 number of effective bits per sample - uint8_t m_nbOriginalBlocks; //!< 11 number of blocks with original (protected) data - uint8_t m_nbFECBlocks; //!< 12 number of blocks carrying FEC - uint32_t m_tv_sec; //!< 16 seconds of timestamp at start time of super-frame processing - 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 MetaDataFEC& rhs) - { - return (memcmp((const char *) this, (const char *) &rhs, 12) == 0); // Only the 12 first bytes are relevant - } - - void init() - { - memset((char *) this, 0, sizeof(MetaDataFEC)); - m_nbFECBlocks = -1; - } - }; - - struct Header - { - uint16_t frameIndex; - uint8_t blockIndex; - uint8_t filler; - uint32_t filler2; - }; - - static const int bytesPerBlock = m_udpSize - sizeof(Header); - - struct ProtectedBlock - { - uint8_t m_buf[bytesPerBlock]; - }; - - struct SuperBlock - { - Header header; - ProtectedBlock protectedBlock; - }; -#pragma pack(pop) +//#pragma pack(push, 1) +// struct MetaDataFEC +// { +// uint32_t m_centerFrequency; //!< 4 center frequency in kHz +// uint32_t m_sampleRate; //!< 8 sample rate in Hz +// uint8_t m_sampleBytes; //!< 9 MSB(4): indicators, LSB(4) number of bytes per sample +// uint8_t m_sampleBits; //!< 10 number of effective bits per sample +// uint8_t m_nbOriginalBlocks; //!< 11 number of blocks with original (protected) data +// uint8_t m_nbFECBlocks; //!< 12 number of blocks carrying FEC +// uint32_t m_tv_sec; //!< 16 seconds of timestamp at start time of super-frame processing +// 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 MetaDataFEC& rhs) +// { +// return (memcmp((const char *) this, (const char *) &rhs, 12) == 0); // Only the 12 first bytes are relevant +// } +// +// void init() +// { +// memset((char *) this, 0, sizeof(MetaDataFEC)); +// m_nbFECBlocks = -1; +// } +// }; +// +// struct Header +// { +// uint16_t frameIndex; +// uint8_t blockIndex; +// uint8_t filler; +// uint32_t filler2; +// }; +// +// static const int bytesPerBlock = m_udpSize - sizeof(Header); +// +// struct ProtectedBlock +// { +// uint8_t m_buf[bytesPerBlock]; +// }; +// +// struct SuperBlock +// { +// Header header; +// ProtectedBlock protectedBlock; +// }; +//#pragma pack(pop) /** * Construct UDP sink @@ -127,8 +128,6 @@ private: std::string m_error; uint32_t m_sampleRate; //!< sample rate in Hz - uint8_t m_sampleBytes; //!< number of bytes per sample - uint8_t m_sampleBits; //!< number of effective bits per sample uint32_t m_nbSamples; //!< total number of samples sent int the last frame QHostAddress m_ownAddress; @@ -137,16 +136,16 @@ private: uint8_t* m_bufMeta; uint8_t* m_buf; - 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 - 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 - int m_sampleIndex; //!< Current sample index in protected block data + SDRDaemonMetaDataFEC 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 + 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 + int m_sampleIndex; //!< Current sample index in protected block data QThread *m_udpThread; UDPSinkFECWorker *m_udpWorker; @@ -161,13 +160,13 @@ public: { MESSAGE_CLASS_DECLARATION public: - UDPSinkFEC::SuperBlock *getTxBlocks() const { return m_txBlockx; } + SDRDaemonSuperBlock *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( - UDPSinkFEC::SuperBlock *txBlocks, + SDRDaemonSuperBlock *txBlocks, uint32_t nbBlocksFEC, uint32_t txDelay, uint16_t frameIndex) @@ -176,13 +175,13 @@ public: } private: - UDPSinkFEC::SuperBlock *m_txBlockx; + SDRDaemonSuperBlock *m_txBlockx; uint32_t m_nbBlocksFEC; uint32_t m_txDelay; uint16_t m_frameIndex; MsgUDPFECEncodeAndSend( - UDPSinkFEC::SuperBlock *txBlocks, + SDRDaemonSuperBlock *txBlocks, uint32_t nbBlocksFEC, uint32_t txDelay, uint16_t frameIndex) : @@ -218,7 +217,7 @@ public: UDPSinkFECWorker(); ~UDPSinkFECWorker(); - void pushTxFrame(UDPSinkFEC::SuperBlock *txBlocks, + void pushTxFrame(SDRDaemonSuperBlock *txBlocks, uint32_t nbBlocksFEC, uint32_t txDelay, uint16_t frameIndex); @@ -237,7 +236,7 @@ private slots: void handleInputMessages(); private: - void encodeAndTransmit(UDPSinkFEC::SuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay); + void encodeAndTransmit(SDRDaemonSuperBlock *txBlockx, uint16_t frameIndex, uint32_t nbBlocksFEC, uint32_t txDelay); volatile bool m_running; CM256 m_cm256; //!< CM256 library object diff --git a/sdrbase/channel/sdrdaemondatablock.h b/sdrbase/channel/sdrdaemondatablock.h index 75d2926b6..1b877f8f1 100644 --- a/sdrbase/channel/sdrdaemondatablock.h +++ b/sdrbase/channel/sdrdaemondatablock.h @@ -38,7 +38,7 @@ struct SDRDaemonMetaDataFEC { uint32_t m_centerFrequency; //!< 4 center frequency in kHz uint32_t m_sampleRate; //!< 8 sample rate in Hz - uint8_t m_sampleBytes; //!< 9 4 LSB: number of bytes per sample (2 or 3) + uint8_t m_sampleBytes; //!< 9 4 LSB: number of bytes per sample (2 or 4) uint8_t m_sampleBits; //!< 10 number of effective bits per sample (deprecated) uint8_t m_nbOriginalBlocks; //!< 11 number of blocks with original (protected) data uint8_t m_nbFECBlocks; //!< 12 number of blocks carrying FEC @@ -69,13 +69,17 @@ struct SDRDaemonHeader { uint16_t m_frameIndex; uint8_t m_blockIndex; + uint8_t m_sampleBytes; //!< number of bytes per sample (2 or 4) for this block + uint8_t m_sampleBits; //!< number of bits per sample uint8_t m_filler; - uint32_t m_filler2; + uint16_t m_filler2; void init() { m_frameIndex = 0; m_blockIndex = 0; + m_sampleBytes = 2; + m_sampleBits = 16; m_filler = 0; m_filler2 = 0; }