mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
Remote sink/input: implemented choice of sample size in transmission.
This commit is contained in:
parent
9278b12e25
commit
ab9f316737
@ -209,6 +209,14 @@ void RemoteSink::applySettings(const RemoteSinkSettings& settings, bool force)
|
||||
frequencyOffsetChange = true;
|
||||
}
|
||||
|
||||
if ((m_settings.m_nbTxBytes != settings.m_nbTxBytes) || force)
|
||||
{
|
||||
reverseAPIKeys.append("nbTxBytes");
|
||||
stop();
|
||||
m_basebandSink->setNbTxBytes(settings.m_nbTxBytes);
|
||||
start();
|
||||
}
|
||||
|
||||
if (m_settings.m_streamIndex != settings.m_streamIndex)
|
||||
{
|
||||
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
|
||||
@ -318,6 +326,10 @@ void RemoteSink::webapiUpdateChannelSettings(
|
||||
}
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("nbTxBytes")) {
|
||||
settings.m_nbTxBytes = response.getRemoteSinkSettings()->getNbTxBytes();
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("dataAddress")) {
|
||||
settings.m_dataAddress = *response.getRemoteSinkSettings()->getDataAddress();
|
||||
}
|
||||
@ -383,6 +395,7 @@ void RemoteSink::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& re
|
||||
response.getRemoteSinkSettings()->setDataAddress(new QString(settings.m_dataAddress));
|
||||
}
|
||||
|
||||
response.getRemoteSinkSettings()->setNbTxBytes(settings.m_nbTxBytes);
|
||||
response.getRemoteSinkSettings()->setDataPort(settings.m_dataPort);
|
||||
response.getRemoteSinkSettings()->setRgbColor(settings.m_rgbColor);
|
||||
|
||||
@ -488,6 +501,9 @@ void RemoteSink::webapiFormatChannelSettings(
|
||||
if (channelSettingsKeys.contains("nbFECBlocks") || force) {
|
||||
swgRemoteSinkSettings->setNbFecBlocks(settings.m_nbFECBlocks);
|
||||
}
|
||||
if (channelSettingsKeys.contains("nbTxBytes") || force) {
|
||||
swgRemoteSinkSettings->setNbTxBytes(settings.m_nbTxBytes);
|
||||
}
|
||||
if (channelSettingsKeys.contains("dataAddress") || force) {
|
||||
swgRemoteSinkSettings->setDataAddress(new QString(settings.m_dataAddress));
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ void RemoteSinkBaseband::reset()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_sampleFifo.reset();
|
||||
m_sink.init();
|
||||
}
|
||||
|
||||
void RemoteSinkBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
@ -155,4 +156,4 @@ void RemoteSinkBaseband::setBasebandSampleRate(int sampleRate)
|
||||
m_basebandSampleRate = sampleRate;
|
||||
m_channelizer->setBasebandSampleRate(m_basebandSampleRate);
|
||||
m_sink.applyBasebandSampleRate(m_basebandSampleRate);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
||||
void startSender() { m_sink.startSender(); }
|
||||
void stopSender() { m_sink.stopSender(); }
|
||||
void setNbTxBytes(uint32_t nbTxBytes) { m_sink.setNbTxBytes(nbTxBytes); }
|
||||
|
||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
||||
int getChannelSampleRate() const;
|
||||
|
@ -168,6 +168,7 @@ void RemoteSinkGUI::displaySettings()
|
||||
QString s = QString::number(128 + m_settings.m_nbFECBlocks, 'f', 0);
|
||||
QString s1 = QString::number(m_settings.m_nbFECBlocks, 'f', 0);
|
||||
ui->nominalNbBlocksText->setText(tr("%1/%2").arg(s).arg(s1));
|
||||
ui->nbTxBytes->setCurrentIndex(log2(m_settings.m_nbTxBytes));
|
||||
applyDecimation();
|
||||
displayStreamIndex();
|
||||
restoreState(m_settings.m_rollupState);
|
||||
@ -333,6 +334,12 @@ void RemoteSinkGUI::on_nbFECBlocks_valueChanged(int value)
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RemoteSinkGUI::on_nbTxBytes_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_nbTxBytes = 1 << index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void RemoteSinkGUI::applyDecimation()
|
||||
{
|
||||
uint32_t maxHash = 1;
|
||||
|
@ -88,6 +88,7 @@ private slots:
|
||||
void on_dataPort_returnPressed();
|
||||
void on_dataApplyButton_clicked(bool checked);
|
||||
void on_nbFECBlocks_valueChanged(int value);
|
||||
void on_nbTxBytes_currentIndexChanged(int index);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void tick();
|
||||
|
@ -395,6 +395,41 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="nbTxBytesLabel">
|
||||
<property name="text">
|
||||
<string>Tx bytes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="nbTxBytes">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Number of transmitted bytes per I or Q sample</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
|
@ -37,6 +37,7 @@ RemoteSinkSettings::RemoteSinkSettings()
|
||||
void RemoteSinkSettings::resetToDefaults()
|
||||
{
|
||||
m_nbFECBlocks = 0;
|
||||
m_nbTxBytes = 2;
|
||||
m_dataAddress = "127.0.0.1";
|
||||
m_dataPort = 9090;
|
||||
m_rgbColor = QColor(140, 4, 4).rgb();
|
||||
@ -56,6 +57,7 @@ QByteArray RemoteSinkSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
s.writeU32(1, m_nbFECBlocks);
|
||||
s.writeU32(2, m_nbTxBytes);
|
||||
s.writeString(3, m_dataAddress);
|
||||
s.writeU32(4, m_dataPort);
|
||||
s.writeU32(5, m_rgbColor);
|
||||
@ -96,6 +98,7 @@ bool RemoteSinkSettings::deserialize(const QByteArray& data)
|
||||
m_nbFECBlocks = 0;
|
||||
}
|
||||
|
||||
d.readU32(2, &m_nbTxBytes, 2);
|
||||
d.readString(3, &m_dataAddress, "127.0.0.1");
|
||||
d.readU32(4, &tmp, 0);
|
||||
|
||||
|
@ -32,6 +32,7 @@ class Serializable;
|
||||
struct RemoteSinkSettings
|
||||
{
|
||||
uint16_t m_nbFECBlocks;
|
||||
uint32_t m_nbTxBytes;
|
||||
QString m_dataAddress;
|
||||
uint16_t m_dataPort;
|
||||
quint32 m_rgbColor;
|
||||
|
@ -36,6 +36,7 @@ RemoteSinkSink::RemoteSinkSink() :
|
||||
m_frequencyOffset(0),
|
||||
m_basebandSampleRate(48000),
|
||||
m_nbBlocksFEC(0),
|
||||
m_nbTxBytes(SDR_RX_SAMP_SZ <= 16 ? 2 : 4),
|
||||
m_dataAddress("127.0.0.1"),
|
||||
m_dataPort(9090)
|
||||
{
|
||||
@ -68,6 +69,14 @@ void RemoteSinkSink::stopSender()
|
||||
m_senderThread->wait();
|
||||
}
|
||||
|
||||
void RemoteSinkSink::init()
|
||||
{
|
||||
m_dataFrame = nullptr;
|
||||
m_txBlockIndex = 0;
|
||||
m_frameCount = 0;
|
||||
m_sampleIndex = 0;
|
||||
}
|
||||
|
||||
void RemoteSinkSink::setNbBlocksFEC(int nbBlocksFEC)
|
||||
{
|
||||
qDebug() << "RemoteSinkSink::setNbBlocksFEC: nbBlocksFEC: " << nbBlocksFEC;
|
||||
@ -92,8 +101,8 @@ void RemoteSinkSink::feed(const SampleVector::const_iterator& begin, const Sampl
|
||||
|
||||
metaData.m_centerFrequency = m_deviceCenterFrequency + m_frequencyOffset;
|
||||
metaData.m_sampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
|
||||
metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4);
|
||||
metaData.m_sampleBits = SDR_RX_SAMP_SZ;
|
||||
metaData.m_sampleBytes = m_nbTxBytes;
|
||||
metaData.m_sampleBits = getNbSampleBits();
|
||||
metaData.m_nbOriginalBlocks = RemoteNbOrginalBlocks;
|
||||
metaData.m_nbFECBlocks = m_nbBlocksFEC;
|
||||
metaData.m_tv_sec = nowus / 1000000UL; // tv.tv_sec;
|
||||
@ -110,8 +119,8 @@ void RemoteSinkSink::feed(const SampleVector::const_iterator& begin, const Sampl
|
||||
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;
|
||||
superBlock.m_header.m_sampleBytes = m_nbTxBytes;
|
||||
superBlock.m_header.m_sampleBits = getNbSampleBits();
|
||||
|
||||
RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &superBlock.m_protectedBlock;
|
||||
*destMeta = metaData;
|
||||
@ -138,24 +147,26 @@ void RemoteSinkSink::feed(const SampleVector::const_iterator& begin, const Sampl
|
||||
int samplesPerBlock = RemoteNbBytesPerBlock / (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)],
|
||||
(const void *) &(*(begin+inSamplesIndex)),
|
||||
inRemainingSamples * sizeof(Sample));
|
||||
convertSampleToData(begin + inSamplesIndex, inRemainingSamples, false);
|
||||
// memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)],
|
||||
// (const void *) &(*(begin+inSamplesIndex)),
|
||||
// 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
|
||||
{
|
||||
memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)],
|
||||
(const void *) &(*(begin+inSamplesIndex)),
|
||||
(samplesPerBlock - m_sampleIndex) * sizeof(Sample));
|
||||
convertSampleToData(begin + inSamplesIndex, samplesPerBlock - m_sampleIndex, false);
|
||||
// memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)],
|
||||
// (const void *) &(*(begin+inSamplesIndex)),
|
||||
// (samplesPerBlock - m_sampleIndex) * sizeof(Sample));
|
||||
it += samplesPerBlock - m_sampleIndex;
|
||||
m_sampleIndex = 0;
|
||||
|
||||
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_superBlock.m_header.m_sampleBytes = m_nbTxBytes;
|
||||
m_superBlock.m_header.m_sampleBits = getNbSampleBits();
|
||||
m_dataFrame->m_superBlocks[m_txBlockIndex] = m_superBlock;
|
||||
|
||||
if (m_txBlockIndex == RemoteNbOrginalBlocks - 1) // frame complete
|
||||
@ -215,3 +226,16 @@ void RemoteSinkSink::applyBasebandSampleRate(uint32_t sampleRate)
|
||||
double shiftFactor = HBFilterChainConverter::getShiftFactor(m_settings.m_log2Decim, m_settings.m_filterChainHash);
|
||||
m_frequencyOffset = round(shiftFactor*m_basebandSampleRate);
|
||||
}
|
||||
|
||||
uint32_t RemoteSinkSink::getNbSampleBits()
|
||||
{
|
||||
if (m_nbTxBytes == 1) {
|
||||
return 8;
|
||||
} else if (m_nbTxBytes == 2) {
|
||||
return 16;
|
||||
} else if (m_nbTxBytes == 4) {
|
||||
return 24;
|
||||
} else {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,9 @@ public:
|
||||
|
||||
void startSender();
|
||||
void stopSender();
|
||||
void init();
|
||||
|
||||
void setNbTxBytes(uint32_t nbTxBytes) { m_nbTxBytes = nbTxBytes; }
|
||||
void applySettings(const RemoteSinkSettings& settings, bool force = false);
|
||||
void applyBasebandSampleRate(uint32_t sampleRate);
|
||||
void setDeviceCenterFrequency(uint64_t frequency) { m_deviceCenterFrequency = frequency; }
|
||||
@ -61,10 +63,78 @@ private:
|
||||
int64_t m_frequencyOffset;
|
||||
uint32_t m_basebandSampleRate;
|
||||
int m_nbBlocksFEC;
|
||||
uint32_t m_nbTxBytes;
|
||||
QString m_dataAddress;
|
||||
uint16_t m_dataPort;
|
||||
|
||||
void setNbBlocksFEC(int nbBlocksFEC);
|
||||
uint32_t getNbSampleBits();
|
||||
|
||||
inline void convertSampleToData(const SampleVector::const_iterator& begin, int nbSamples, bool isTx)
|
||||
{
|
||||
if (sizeof(Sample) == m_nbTxBytes * 2) // 16 -> 16 or 24 ->24: direct copy
|
||||
{
|
||||
memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*m_nbTxBytes*2],
|
||||
(const void *) &(*(begin)),
|
||||
nbSamples * sizeof(Sample));
|
||||
}
|
||||
else if (isTx)
|
||||
{
|
||||
if (m_nbTxBytes == 4) // just convert type int16_t -> int32_t (always 16 bit wide)
|
||||
{
|
||||
for (int i = 0; i < nbSamples; i++)
|
||||
{
|
||||
*((int32_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2]) = (begin+i)->m_real;
|
||||
*((int32_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2 + m_nbTxBytes]) = (begin+i)->m_imag;
|
||||
}
|
||||
}
|
||||
else if (m_nbTxBytes == 2) //just convert type int32_t -> int16_t (always 16 bit wide)
|
||||
{
|
||||
for (int i = 0; i < nbSamples; i++)
|
||||
{
|
||||
*((int16_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2]) = (begin+i)->m_real;
|
||||
*((int16_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2 + m_nbTxBytes]) = (begin+i)->m_imag;
|
||||
}
|
||||
}
|
||||
else if (m_nbTxBytes == 1) // 16 -> 8
|
||||
{
|
||||
for (int i = 0; i < nbSamples; i++)
|
||||
{
|
||||
m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2] = (uint8_t) ((begin+i)->m_real / 256);
|
||||
m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2 + m_nbTxBytes] = (uint8_t) ((begin+i)->m_imag / 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_nbTxBytes == 4) // 16 -> 24
|
||||
{
|
||||
for (int i = 0; i < nbSamples; i++)
|
||||
{
|
||||
*((int32_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2]) = (begin+i)->m_real << 8;
|
||||
*((int32_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2 + m_nbTxBytes]) = (begin+i)->m_imag << 8;
|
||||
}
|
||||
}
|
||||
else if (m_nbTxBytes == 2) // 24 -> 16
|
||||
{
|
||||
for (int i = 0; i < nbSamples; i++)
|
||||
{
|
||||
*((int16_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2]) = (begin+i)->m_real >> 8;
|
||||
*((int16_t*) &m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2 + m_nbTxBytes]) = (begin+i)->m_imag >> 8;
|
||||
}
|
||||
}
|
||||
else if (m_nbTxBytes == 1) // 16 or 24 -> 8
|
||||
{
|
||||
for (int i = 0; i < nbSamples; i++)
|
||||
{
|
||||
m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2] =
|
||||
(uint8_t) (((begin+i)->m_real / (1<<sizeof(Sample)*2)) & 0xFF);
|
||||
m_superBlock.m_protectedBlock.buf[(m_sampleIndex+ i)*m_nbTxBytes*2 + m_nbTxBytes] =
|
||||
(uint8_t) (((begin+i)->m_imag / (1<<sizeof(Sample)*2)) & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // INCLUDE_REMOTESINKSINK_H_
|
||||
|
@ -45,6 +45,10 @@ This is the device set index in the remote instance to which the stream is conne
|
||||
|
||||
This is the channel index of the Remote source in the remote instance to which the stream is connected to. Use this value to properly address the API to get status.
|
||||
|
||||
<h3>6a: transmission sample size</h3>
|
||||
|
||||
This is the size in bytes of a transmitted I or Q sample. The choice is between 1, 2 and 4 bytes. Conversion takes place if the size is different from the built-in sample size.
|
||||
|
||||
<h3>7: Forward Error Correction setting and status</h3>
|
||||
|
||||
![SDR Remote output FEC GUI](../../../doc/img/RemoteOutput_plugin_06.png)
|
||||
|
@ -35,7 +35,6 @@ UDPSinkFEC::UDPSinkFEC() :
|
||||
m_txDelayRatio(0.0),
|
||||
m_dataFrame(nullptr),
|
||||
m_txBlockIndex(0),
|
||||
m_txBlocksIndex(0),
|
||||
m_frameCount(0),
|
||||
m_sampleIndex(0),
|
||||
m_remoteOutputSender(nullptr),
|
||||
@ -61,7 +60,6 @@ void UDPSinkFEC::init()
|
||||
{
|
||||
m_dataFrame = nullptr;
|
||||
m_txBlockIndex = 0;
|
||||
m_txBlocksIndex = 0;
|
||||
m_frameCount = 0;
|
||||
m_sampleIndex = 0;
|
||||
}
|
||||
|
@ -92,7 +92,6 @@ private:
|
||||
RemoteDataFrame *m_dataFrame;
|
||||
RemoteSuperBlock 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
|
||||
|
||||
|
@ -326,7 +326,50 @@ void RemoteInputUDPHandler::tick()
|
||||
const RemoteMetaDataFEC& metaData = m_remoteInputBuffer.getCurrentMeta();
|
||||
m_readLength = m_readLengthSamples * (metaData.m_sampleBytes & 0xF) * 2;
|
||||
|
||||
if ((metaData.m_sampleBits == 16) && (SDR_RX_SAMP_SZ == 24)) // 16 -> 24 bits
|
||||
if (metaData.m_sampleBits == SDR_RX_SAMP_SZ) // no conversion
|
||||
{
|
||||
// read samples directly feeding the SampleFifo (no callback)
|
||||
m_sampleFifo->write(reinterpret_cast<quint8*>(m_remoteInputBuffer.readData(m_readLength)), m_readLength);
|
||||
m_samplesCount += m_readLengthSamples;
|
||||
}
|
||||
else if ((metaData.m_sampleBits == 8) && (SDR_RX_SAMP_SZ == 16)) // 8 -> 16
|
||||
{
|
||||
if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
{
|
||||
if (m_converterBuffer) { delete[] m_converterBuffer; }
|
||||
m_converterBuffer = new int32_t[m_readLengthSamples];
|
||||
}
|
||||
|
||||
uint8_t *buf = m_remoteInputBuffer.readData(m_readLength);
|
||||
|
||||
for (int is = 0; is < m_readLengthSamples; is++)
|
||||
{
|
||||
m_converterBuffer[is] = buf[2*is+1] << 8; // Q -> MSB
|
||||
m_converterBuffer[is] <<= 16;
|
||||
m_converterBuffer[is] += buf[2*is] << 8; // I -> LSB
|
||||
}
|
||||
}
|
||||
else if ((metaData.m_sampleBits == 8) && (SDR_RX_SAMP_SZ == 24)) // 8 -> 24
|
||||
{
|
||||
if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
{
|
||||
if (m_converterBuffer) { delete[] m_converterBuffer; }
|
||||
m_converterBuffer = new int32_t[m_readLengthSamples*2];
|
||||
}
|
||||
|
||||
uint8_t *buf = m_remoteInputBuffer.readData(m_readLength);
|
||||
|
||||
for (int is = 0; is < m_readLengthSamples; is++)
|
||||
{
|
||||
m_converterBuffer[2*is] = buf[2*is]; // I
|
||||
m_converterBuffer[2*is] <<= 16;
|
||||
m_converterBuffer[2*is+1] = buf[2*is+1]; // Q
|
||||
m_converterBuffer[2*is+1] <<= 16;
|
||||
}
|
||||
|
||||
m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
}
|
||||
else if (metaData.m_sampleBits == 16) // 16 -> 24
|
||||
{
|
||||
if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
{
|
||||
@ -339,14 +382,14 @@ void RemoteInputUDPHandler::tick()
|
||||
for (int is = 0; is < m_readLengthSamples; is++)
|
||||
{
|
||||
m_converterBuffer[2*is] = ((int16_t*)buf)[2*is]; // I
|
||||
m_converterBuffer[2*is]<<=8;
|
||||
m_converterBuffer[2*is] <<= 8;
|
||||
m_converterBuffer[2*is+1] = ((int16_t*)buf)[2*is+1]; // Q
|
||||
m_converterBuffer[2*is+1]<<=8;
|
||||
m_converterBuffer[2*is+1] <<= 8;
|
||||
}
|
||||
|
||||
m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
}
|
||||
else if ((metaData.m_sampleBits == 24) && (SDR_RX_SAMP_SZ == 16)) // 24 -> 16 bits
|
||||
else if (metaData.m_sampleBits == 24) // 24 -> 16
|
||||
{
|
||||
if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
{
|
||||
@ -359,23 +402,67 @@ void RemoteInputUDPHandler::tick()
|
||||
for (int is = 0; is < m_readLengthSamples; is++)
|
||||
{
|
||||
m_converterBuffer[is] = ((int32_t *)buf)[2*is+1]>>8; // Q -> MSB
|
||||
m_converterBuffer[is] <<=16;
|
||||
m_converterBuffer[is] <<= 16;
|
||||
m_converterBuffer[is] += ((int32_t *)buf)[2*is]>>8; // I -> LSB
|
||||
}
|
||||
|
||||
m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
}
|
||||
else if ((metaData.m_sampleBits == 16) || (metaData.m_sampleBits == 24)) // same sample size and valid size
|
||||
{
|
||||
// read samples directly feeding the SampleFifo (no callback)
|
||||
m_sampleFifo->write(reinterpret_cast<quint8*>(m_remoteInputBuffer.readData(m_readLength)), m_readLength);
|
||||
m_samplesCount += m_readLengthSamples;
|
||||
}
|
||||
else // invalid size
|
||||
{
|
||||
qWarning("RemoteInputUDPHandler::tick: unexpected sample size in stream: %d bits", (int) metaData.m_sampleBits);
|
||||
}
|
||||
|
||||
// if ((metaData.m_sampleBits == 16) && (SDR_RX_SAMP_SZ == 24)) // 16 -> 24 bits
|
||||
// {
|
||||
// if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
// {
|
||||
// if (m_converterBuffer) { delete[] m_converterBuffer; }
|
||||
// m_converterBuffer = new int32_t[m_readLengthSamples*2];
|
||||
// }
|
||||
|
||||
// uint8_t *buf = m_remoteInputBuffer.readData(m_readLength);
|
||||
|
||||
// for (int is = 0; is < m_readLengthSamples; is++)
|
||||
// {
|
||||
// m_converterBuffer[2*is] = ((int16_t*)buf)[2*is]; // I
|
||||
// m_converterBuffer[2*is]<<=8;
|
||||
// m_converterBuffer[2*is+1] = ((int16_t*)buf)[2*is+1]; // Q
|
||||
// m_converterBuffer[2*is+1]<<=8;
|
||||
// }
|
||||
|
||||
// m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
// }
|
||||
// else if ((metaData.m_sampleBits == 24) && (SDR_RX_SAMP_SZ == 16)) // 24 -> 16 bits
|
||||
// {
|
||||
// if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
// {
|
||||
// if (m_converterBuffer) { delete[] m_converterBuffer; }
|
||||
// m_converterBuffer = new int32_t[m_readLengthSamples];
|
||||
// }
|
||||
|
||||
// uint8_t *buf = m_remoteInputBuffer.readData(m_readLength);
|
||||
|
||||
// for (int is = 0; is < m_readLengthSamples; is++)
|
||||
// {
|
||||
// m_converterBuffer[is] = ((int32_t *)buf)[2*is+1]>>8; // Q -> MSB
|
||||
// m_converterBuffer[is] <<=16;
|
||||
// m_converterBuffer[is] += ((int32_t *)buf)[2*is]>>8; // I -> LSB
|
||||
// }
|
||||
|
||||
// m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
// }
|
||||
// else if ((metaData.m_sampleBits == 16) || (metaData.m_sampleBits == 24)) // same sample size and valid size
|
||||
// {
|
||||
// // read samples directly feeding the SampleFifo (no callback)
|
||||
// m_sampleFifo->write(reinterpret_cast<quint8*>(m_remoteInputBuffer.readData(m_readLength)), m_readLength);
|
||||
// m_samplesCount += m_readLengthSamples;
|
||||
// }
|
||||
// else // invalid size
|
||||
// {
|
||||
// qWarning("RemoteInputUDPHandler::tick: unexpected sample size in stream: %d bits", (int) metaData.m_sampleBits);
|
||||
// }
|
||||
|
||||
if (m_tickCount < m_rateDivider)
|
||||
{
|
||||
m_tickCount++;
|
||||
|
@ -9864,7 +9864,8 @@ margin-bottom: 20px;
|
||||
"type" : "integer"
|
||||
},
|
||||
"nbTxBytes" : {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"description" : "Number of bytes in a transmited I or Q sample\n * 1\n * 2\n * 4\n"
|
||||
},
|
||||
"apiAddress" : {
|
||||
"type" : "string"
|
||||
@ -9906,6 +9907,10 @@ margin-bottom: 20px;
|
||||
"type" : "integer",
|
||||
"description" : "Number of FEC blocks per frame"
|
||||
},
|
||||
"nbTxBytes" : {
|
||||
"type" : "integer",
|
||||
"description" : "Number of bytes in a transmited I or Q sample\n * 1\n * 2\n * 4\n"
|
||||
},
|
||||
"dataAddress" : {
|
||||
"type" : "string",
|
||||
"description" : "Receiving USB data address"
|
||||
@ -51625,7 +51630,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2021-12-18T22:54:13.645+01:00
|
||||
Generated 2021-12-19T12:04:51.409+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,6 +5,11 @@ RemoteOutputSettings:
|
||||
type: integer
|
||||
nbTxBytes:
|
||||
type: integer
|
||||
description: >
|
||||
Number of bytes in a transmited I or Q sample
|
||||
* 1
|
||||
* 2
|
||||
* 4
|
||||
apiAddress:
|
||||
type: string
|
||||
apiPort:
|
||||
|
@ -4,6 +4,13 @@ RemoteSinkSettings:
|
||||
nbFECBlocks:
|
||||
description: "Number of FEC blocks per frame"
|
||||
type: integer
|
||||
nbTxBytes:
|
||||
type: integer
|
||||
description: >
|
||||
Number of bytes in a transmited I or Q sample
|
||||
* 1
|
||||
* 2
|
||||
* 4
|
||||
dataAddress:
|
||||
description: "Receiving USB data address"
|
||||
type: string
|
||||
|
@ -5,6 +5,11 @@ RemoteOutputSettings:
|
||||
type: integer
|
||||
nbTxBytes:
|
||||
type: integer
|
||||
description: >
|
||||
Number of bytes in a transmited I or Q sample
|
||||
* 1
|
||||
* 2
|
||||
* 4
|
||||
apiAddress:
|
||||
type: string
|
||||
apiPort:
|
||||
|
@ -4,6 +4,13 @@ RemoteSinkSettings:
|
||||
nbFECBlocks:
|
||||
description: "Number of FEC blocks per frame"
|
||||
type: integer
|
||||
nbTxBytes:
|
||||
type: integer
|
||||
description: >
|
||||
Number of bytes in a transmited I or Q sample
|
||||
* 1
|
||||
* 2
|
||||
* 4
|
||||
dataAddress:
|
||||
description: "Receiving USB data address"
|
||||
type: string
|
||||
|
@ -9864,7 +9864,8 @@ margin-bottom: 20px;
|
||||
"type" : "integer"
|
||||
},
|
||||
"nbTxBytes" : {
|
||||
"type" : "integer"
|
||||
"type" : "integer",
|
||||
"description" : "Number of bytes in a transmited I or Q sample\n * 1\n * 2\n * 4\n"
|
||||
},
|
||||
"apiAddress" : {
|
||||
"type" : "string"
|
||||
@ -9906,6 +9907,10 @@ margin-bottom: 20px;
|
||||
"type" : "integer",
|
||||
"description" : "Number of FEC blocks per frame"
|
||||
},
|
||||
"nbTxBytes" : {
|
||||
"type" : "integer",
|
||||
"description" : "Number of bytes in a transmited I or Q sample\n * 1\n * 2\n * 4\n"
|
||||
},
|
||||
"dataAddress" : {
|
||||
"type" : "string",
|
||||
"description" : "Receiving USB data address"
|
||||
@ -51625,7 +51630,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2021-12-18T22:54:13.645+01:00
|
||||
Generated 2021-12-19T12:04:51.409+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,6 +30,8 @@ SWGRemoteSinkSettings::SWGRemoteSinkSettings(QString* json) {
|
||||
SWGRemoteSinkSettings::SWGRemoteSinkSettings() {
|
||||
nb_fec_blocks = 0;
|
||||
m_nb_fec_blocks_isSet = false;
|
||||
nb_tx_bytes = 0;
|
||||
m_nb_tx_bytes_isSet = false;
|
||||
data_address = nullptr;
|
||||
m_data_address_isSet = false;
|
||||
data_port = 0;
|
||||
@ -66,6 +68,8 @@ void
|
||||
SWGRemoteSinkSettings::init() {
|
||||
nb_fec_blocks = 0;
|
||||
m_nb_fec_blocks_isSet = false;
|
||||
nb_tx_bytes = 0;
|
||||
m_nb_tx_bytes_isSet = false;
|
||||
data_address = new QString("");
|
||||
m_data_address_isSet = false;
|
||||
data_port = 0;
|
||||
@ -97,6 +101,7 @@ SWGRemoteSinkSettings::init() {
|
||||
void
|
||||
SWGRemoteSinkSettings::cleanup() {
|
||||
|
||||
|
||||
if(data_address != nullptr) {
|
||||
delete data_address;
|
||||
}
|
||||
@ -133,6 +138,8 @@ void
|
||||
SWGRemoteSinkSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&nb_fec_blocks, pJson["nbFECBlocks"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&nb_tx_bytes, pJson["nbTxBytes"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&data_address, pJson["dataAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&data_port, pJson["dataPort"], "qint32", "");
|
||||
@ -178,6 +185,9 @@ SWGRemoteSinkSettings::asJsonObject() {
|
||||
if(m_nb_fec_blocks_isSet){
|
||||
obj->insert("nbFECBlocks", QJsonValue(nb_fec_blocks));
|
||||
}
|
||||
if(m_nb_tx_bytes_isSet){
|
||||
obj->insert("nbTxBytes", QJsonValue(nb_tx_bytes));
|
||||
}
|
||||
if(data_address != nullptr && *data_address != QString("")){
|
||||
toJsonValue(QString("dataAddress"), data_address, obj, QString("QString"));
|
||||
}
|
||||
@ -231,6 +241,16 @@ SWGRemoteSinkSettings::setNbFecBlocks(qint32 nb_fec_blocks) {
|
||||
this->m_nb_fec_blocks_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRemoteSinkSettings::getNbTxBytes() {
|
||||
return nb_tx_bytes;
|
||||
}
|
||||
void
|
||||
SWGRemoteSinkSettings::setNbTxBytes(qint32 nb_tx_bytes) {
|
||||
this->nb_tx_bytes = nb_tx_bytes;
|
||||
this->m_nb_tx_bytes_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRemoteSinkSettings::getDataAddress() {
|
||||
return data_address;
|
||||
@ -369,6 +389,9 @@ SWGRemoteSinkSettings::isSet(){
|
||||
if(m_nb_fec_blocks_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_nb_tx_bytes_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(data_address && *data_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ public:
|
||||
qint32 getNbFecBlocks();
|
||||
void setNbFecBlocks(qint32 nb_fec_blocks);
|
||||
|
||||
qint32 getNbTxBytes();
|
||||
void setNbTxBytes(qint32 nb_tx_bytes);
|
||||
|
||||
QString* getDataAddress();
|
||||
void setDataAddress(QString* data_address);
|
||||
|
||||
@ -92,6 +95,9 @@ private:
|
||||
qint32 nb_fec_blocks;
|
||||
bool m_nb_fec_blocks_isSet;
|
||||
|
||||
qint32 nb_tx_bytes;
|
||||
bool m_nb_tx_bytes_isSet;
|
||||
|
||||
QString* data_address;
|
||||
bool m_data_address_isSet;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user