diff --git a/plugins/channelrx/daemonsink/daemonsink.cpp b/plugins/channelrx/daemonsink/daemonsink.cpp index a30dacc12..2b69618dc 100644 --- a/plugins/channelrx/daemonsink/daemonsink.cpp +++ b/plugins/channelrx/daemonsink/daemonsink.cpp @@ -82,7 +82,8 @@ DaemonSink::~DaemonSink() void DaemonSink::setTxDelay(int txDelay, int nbBlocksFEC) { double txDelayRatio = txDelay / 100.0; - double delay = m_sampleRate == 0 ? 1.0 : (127*SDRDaemonSamplesPerBlock*txDelayRatio) / m_sampleRate; + int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); + double delay = m_sampleRate == 0 ? 1.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate; delay /= 128 + nbBlocksFEC; m_txDelay = roundf(delay*1e6); // microseconds qDebug() << "DaemonSink::setTxDelay:" @@ -152,10 +153,11 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec m_txBlockIndex = 1; // next Tx block with data } // block zero - // TODO: handle different sample sizes... - if (m_sampleIndex + inRemainingSamples < SDRDaemonSamplesPerBlock) // there is still room in the current super block + // handle different sample sizes... + int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); + if (m_sampleIndex + inRemainingSamples < samplesPerBlock) // there is still room in the current super block { - memcpy((void *) &m_superBlock.m_protectedBlock.m_samples[m_sampleIndex], + memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], (const void *) &(*(begin+inSamplesIndex)), inRemainingSamples * sizeof(Sample)); m_sampleIndex += inRemainingSamples; @@ -163,10 +165,10 @@ void DaemonSink::feed(const SampleVector::const_iterator& begin, const SampleVec } else // complete super block and initiate the next if not end of frame { - memcpy((void *) &m_superBlock.m_protectedBlock.m_samples[m_sampleIndex], + memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], (const void *) &(*(begin+inSamplesIndex)), - (SDRDaemonSamplesPerBlock - m_sampleIndex) * sizeof(Sample)); - it += SDRDaemonSamplesPerBlock - m_sampleIndex; + (samplesPerBlock - m_sampleIndex) * sizeof(Sample)); + it += samplesPerBlock - m_sampleIndex; m_sampleIndex = 0; m_superBlock.m_header.m_frameIndex = m_frameCount; diff --git a/plugins/channelrx/daemonsink/daemonsinkgui.cpp b/plugins/channelrx/daemonsink/daemonsinkgui.cpp index 1900958b0..83338b822 100644 --- a/plugins/channelrx/daemonsink/daemonsinkgui.cpp +++ b/plugins/channelrx/daemonsink/daemonsinkgui.cpp @@ -287,7 +287,8 @@ void DaemonSinkGUI::on_nbFECBlocks_valueChanged(int value) void DaemonSinkGUI::updateTxDelayTime() { double txDelayRatio = m_settings.m_txDelay / 100.0; - double delay = m_sampleRate == 0 ? 0.0 : (127*SDRDaemonSamplesPerBlock*txDelayRatio) / m_sampleRate; + int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); + double delay = m_sampleRate == 0 ? 0.0 : (127*samplesPerBlock*txDelayRatio) / m_sampleRate; delay /= 128 + m_settings.m_nbFECBlocks; ui->txDelayTime->setText(tr("%1µs").arg(QString::number(delay*1e6, 'f', 0))); } diff --git a/plugins/channeltx/daemonsrc/daemonsrc.cpp b/plugins/channeltx/daemonsrc/daemonsrc.cpp index e6f711ca1..d793da79d 100644 --- a/plugins/channeltx/daemonsrc/daemonsrc.cpp +++ b/plugins/channeltx/daemonsrc/daemonsrc.cpp @@ -46,6 +46,7 @@ DaemonSrc::DaemonSrc(DeviceSinkAPI *deviceAPI) : m_deviceAPI(deviceAPI), m_sourceThread(0), m_running(false), + m_dataReadQueue(SDR_TX_SAMP_SZ <= 16 ? 4 : 8), m_nbCorrectableErrors(0), m_nbUncorrectableErrors(0) { diff --git a/sdrdaemon/channel/sdrdaemonchannelsink.cpp b/sdrdaemon/channel/sdrdaemonchannelsink.cpp index c21e6e902..2d929450b 100644 --- a/sdrdaemon/channel/sdrdaemonchannelsink.cpp +++ b/sdrdaemon/channel/sdrdaemonchannelsink.cpp @@ -147,10 +147,11 @@ void SDRDaemonChannelSink::feed(const SampleVector::const_iterator& begin, const m_txBlockIndex = 1; // next Tx block with data } // block zero - // TODO: handle different sample sizes... - if (m_sampleIndex + inRemainingSamples < SDRDaemonSamplesPerBlock) // there is still room in the current super block + // handle different sample sizes... + int samplesPerBlock = SDRDaemonNbBytesPerBlock / sizeof(Sample); + if (m_sampleIndex + inRemainingSamples < samplesPerBlock) // there is still room in the current super block { - memcpy((void *) &m_superBlock.m_protectedBlock.m_samples[m_sampleIndex], + memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], (const void *) &(*(begin+inSamplesIndex)), inRemainingSamples * sizeof(Sample)); m_sampleIndex += inRemainingSamples; @@ -158,10 +159,10 @@ void SDRDaemonChannelSink::feed(const SampleVector::const_iterator& begin, const } else // complete super block and initiate the next if not end of frame { - memcpy((void *) &m_superBlock.m_protectedBlock.m_samples[m_sampleIndex], + memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], (const void *) &(*(begin+inSamplesIndex)), - (SDRDaemonSamplesPerBlock - m_sampleIndex) * sizeof(Sample)); - it += SDRDaemonSamplesPerBlock - m_sampleIndex; + (samplesPerBlock - m_sampleIndex) * sizeof(Sample)); + it += samplesPerBlock - m_sampleIndex; m_sampleIndex = 0; m_superBlock.m_header.m_frameIndex = m_frameCount; diff --git a/sdrdaemon/channel/sdrdaemonchannelsource.cpp b/sdrdaemon/channel/sdrdaemonchannelsource.cpp index 43f879cd5..9d0141272 100644 --- a/sdrdaemon/channel/sdrdaemonchannelsource.cpp +++ b/sdrdaemon/channel/sdrdaemonchannelsource.cpp @@ -50,6 +50,7 @@ SDRDaemonChannelSource::SDRDaemonChannelSource(DeviceSinkAPI *deviceAPI) : m_deviceAPI(deviceAPI), m_sourceThread(0), m_running(false), + m_dataReadQueue(SDR_TX_SAMP_SZ <= 16 ? 4 : 8), m_nbCorrectableErrors(0), m_nbUncorrectableErrors(0) { diff --git a/sdrdaemon/channel/sdrdaemondatablock.h b/sdrdaemon/channel/sdrdaemondatablock.h index 6138fa729..75d2926b6 100644 --- a/sdrdaemon/channel/sdrdaemondatablock.h +++ b/sdrdaemon/channel/sdrdaemondatablock.h @@ -83,14 +83,14 @@ struct SDRDaemonHeader static const int SDRDaemonUdpSize = UDPSINKFEC_UDPSIZE; static const int SDRDaemonNbOrginalBlocks = UDPSINKFEC_NBORIGINALBLOCKS; -static const int SDRDaemonSamplesPerBlock = (UDPSINKFEC_UDPSIZE - sizeof(SDRDaemonHeader)) / sizeof(Sample); +static const int SDRDaemonNbBytesPerBlock = UDPSINKFEC_UDPSIZE - sizeof(SDRDaemonHeader); struct SDRDaemonProtectedBlock { - Sample m_samples[SDRDaemonSamplesPerBlock]; + uint8_t buf[SDRDaemonNbBytesPerBlock]; void init() { - std::fill(m_samples, m_samples+SDRDaemonSamplesPerBlock, Sample{0,0}); + std::fill(buf, buf+SDRDaemonNbBytesPerBlock, 0); } }; diff --git a/sdrdaemon/channel/sdrdaemondatareadqueue.cpp b/sdrdaemon/channel/sdrdaemondatareadqueue.cpp index b14921166..c71158771 100644 --- a/sdrdaemon/channel/sdrdaemondatareadqueue.cpp +++ b/sdrdaemon/channel/sdrdaemondatareadqueue.cpp @@ -25,7 +25,8 @@ const uint32_t SDRDaemonDataReadQueue::MinimumMaxSize = 10; -SDRDaemonDataReadQueue::SDRDaemonDataReadQueue() : +SDRDaemonDataReadQueue::SDRDaemonDataReadQueue(uint32_t sampleSize) : + m_sampleSize(sampleSize), m_dataBlock(0), m_maxSize(MinimumMaxSize), m_blockIndex(1), @@ -95,7 +96,7 @@ void SDRDaemonDataReadQueue::readSample(Sample& s) qDebug("SDRDaemonDataReadQueue::readSample: initial pop new block: queue size: %u", length()); m_blockIndex = 1; m_dataBlock = m_dataReadQueue.takeFirst(); - s = m_dataBlock->m_superBlocks[m_blockIndex].m_protectedBlock.m_samples[m_sampleIndex]; + convertDataToSample(s, m_blockIndex, m_sampleIndex); m_sampleIndex++; m_sampleCount++; } @@ -107,9 +108,11 @@ void SDRDaemonDataReadQueue::readSample(Sample& s) return; } - if (m_sampleIndex < SDRDaemonSamplesPerBlock) + uint32_t samplesPerBlock = SDRDaemonNbBytesPerBlock / m_sampleSize; + + if (m_sampleIndex < samplesPerBlock) { - s = m_dataBlock->m_superBlocks[m_blockIndex].m_protectedBlock.m_samples[m_sampleIndex]; + convertDataToSample(s, m_blockIndex, m_sampleIndex); m_sampleIndex++; m_sampleCount++; } @@ -120,7 +123,7 @@ void SDRDaemonDataReadQueue::readSample(Sample& s) if (m_blockIndex < SDRDaemonNbOrginalBlocks) { - s = m_dataBlock->m_superBlocks[m_blockIndex].m_protectedBlock.m_samples[m_sampleIndex]; + convertDataToSample(s, m_blockIndex, m_sampleIndex); m_sampleIndex++; m_sampleCount++; } @@ -141,7 +144,7 @@ void SDRDaemonDataReadQueue::readSample(Sample& s) //qDebug("SDRDaemonDataReadQueue::readSample: pop new block: queue size: %u", length()); m_blockIndex = 1; m_dataBlock = m_dataReadQueue.takeFirst(); - s = m_dataBlock->m_superBlocks[m_blockIndex].m_protectedBlock.m_samples[m_sampleIndex]; + convertDataToSample(s, m_blockIndex, m_sampleIndex); m_sampleIndex++; m_sampleCount++; } diff --git a/sdrdaemon/channel/sdrdaemondatareadqueue.h b/sdrdaemon/channel/sdrdaemondatareadqueue.h index ba43d2c47..c20a8f9c6 100644 --- a/sdrdaemon/channel/sdrdaemondatareadqueue.h +++ b/sdrdaemon/channel/sdrdaemondatareadqueue.h @@ -31,7 +31,7 @@ class Sample; class SDRDaemonDataReadQueue { public: - SDRDaemonDataReadQueue(); + SDRDaemonDataReadQueue(uint32_t sampleSize); ~SDRDaemonDataReadQueue(); void push(SDRDaemonDataBlock* dataBlock); //!< push block on the queue @@ -45,6 +45,7 @@ public: static const uint32_t MinimumMaxSize; private: + uint32_t m_sampleSize; QQueue m_dataReadQueue; SDRDaemonDataBlock *m_dataBlock; uint32_t m_maxSize; @@ -52,6 +53,32 @@ private: uint32_t m_sampleIndex; uint32_t m_sampleCount; //!< use a counter capped below 2^31 as it is going to be converted to an int in the web interface bool m_full; //!< full condition was hit + + inline void convertDataToSample(Sample& s, uint32_t blockIndex, uint32_t sampleIndex) + { + if (sizeof(Sample) == m_sampleSize) + { + s = *((Sample*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*m_sampleSize])); + } + else if ((sizeof(Sample) == 4) && (m_sampleSize == 8)) + { + int32_t rp = *( (int32_t*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*m_sampleSize]) ); + int32_t ip = *( (int32_t*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*m_sampleSize+4]) ); + s.setReal(rp>>8); + s.setImag(ip>>8); + } + else if ((sizeof(Sample) == 8) && (m_sampleSize == 4)) + { + int32_t rp = *( (int16_t*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*m_sampleSize]) ); + int32_t ip = *( (int16_t*) &(m_dataBlock->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*m_sampleSize+2]) ); + s.setReal(rp<<8); + s.setImag(ip<<8); + } + else + { + s = Sample{0, 0}; + } + } };