1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-21 23:55:13 -05:00

Remote sink/input: implemented choice of sample size in transmission.

This commit is contained in:
f4exb 2021-12-19 13:15:17 +01:00
parent 9278b12e25
commit ab9f316737
22 changed files with 341 additions and 31 deletions

View File

@ -209,6 +209,14 @@ void RemoteSink::applySettings(const RemoteSinkSettings& settings, bool force)
frequencyOffsetChange = true; 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_settings.m_streamIndex != settings.m_streamIndex)
{ {
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only 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")) { if (channelSettingsKeys.contains("dataAddress")) {
settings.m_dataAddress = *response.getRemoteSinkSettings()->getDataAddress(); 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()->setDataAddress(new QString(settings.m_dataAddress));
} }
response.getRemoteSinkSettings()->setNbTxBytes(settings.m_nbTxBytes);
response.getRemoteSinkSettings()->setDataPort(settings.m_dataPort); response.getRemoteSinkSettings()->setDataPort(settings.m_dataPort);
response.getRemoteSinkSettings()->setRgbColor(settings.m_rgbColor); response.getRemoteSinkSettings()->setRgbColor(settings.m_rgbColor);
@ -488,6 +501,9 @@ void RemoteSink::webapiFormatChannelSettings(
if (channelSettingsKeys.contains("nbFECBlocks") || force) { if (channelSettingsKeys.contains("nbFECBlocks") || force) {
swgRemoteSinkSettings->setNbFecBlocks(settings.m_nbFECBlocks); swgRemoteSinkSettings->setNbFecBlocks(settings.m_nbFECBlocks);
} }
if (channelSettingsKeys.contains("nbTxBytes") || force) {
swgRemoteSinkSettings->setNbTxBytes(settings.m_nbTxBytes);
}
if (channelSettingsKeys.contains("dataAddress") || force) { if (channelSettingsKeys.contains("dataAddress") || force) {
swgRemoteSinkSettings->setDataAddress(new QString(settings.m_dataAddress)); swgRemoteSinkSettings->setDataAddress(new QString(settings.m_dataAddress));
} }

View File

@ -52,6 +52,7 @@ void RemoteSinkBaseband::reset()
{ {
QMutexLocker mutexLocker(&m_mutex); QMutexLocker mutexLocker(&m_mutex);
m_sampleFifo.reset(); m_sampleFifo.reset();
m_sink.init();
} }
void RemoteSinkBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end) 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_basebandSampleRate = sampleRate;
m_channelizer->setBasebandSampleRate(m_basebandSampleRate); m_channelizer->setBasebandSampleRate(m_basebandSampleRate);
m_sink.applyBasebandSampleRate(m_basebandSampleRate); m_sink.applyBasebandSampleRate(m_basebandSampleRate);
} }

View File

@ -64,6 +64,7 @@ public:
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
void startSender() { m_sink.startSender(); } void startSender() { m_sink.startSender(); }
void stopSender() { m_sink.stopSender(); } 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 MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
int getChannelSampleRate() const; int getChannelSampleRate() const;

View File

@ -168,6 +168,7 @@ void RemoteSinkGUI::displaySettings()
QString s = QString::number(128 + m_settings.m_nbFECBlocks, 'f', 0); QString s = QString::number(128 + m_settings.m_nbFECBlocks, 'f', 0);
QString s1 = QString::number(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->nominalNbBlocksText->setText(tr("%1/%2").arg(s).arg(s1));
ui->nbTxBytes->setCurrentIndex(log2(m_settings.m_nbTxBytes));
applyDecimation(); applyDecimation();
displayStreamIndex(); displayStreamIndex();
restoreState(m_settings.m_rollupState); restoreState(m_settings.m_rollupState);
@ -333,6 +334,12 @@ void RemoteSinkGUI::on_nbFECBlocks_valueChanged(int value)
applySettings(); applySettings();
} }
void RemoteSinkGUI::on_nbTxBytes_currentIndexChanged(int index)
{
m_settings.m_nbTxBytes = 1 << index;
applySettings();
}
void RemoteSinkGUI::applyDecimation() void RemoteSinkGUI::applyDecimation()
{ {
uint32_t maxHash = 1; uint32_t maxHash = 1;

View File

@ -88,6 +88,7 @@ private slots:
void on_dataPort_returnPressed(); void on_dataPort_returnPressed();
void on_dataApplyButton_clicked(bool checked); void on_dataApplyButton_clicked(bool checked);
void on_nbFECBlocks_valueChanged(int value); void on_nbFECBlocks_valueChanged(int value);
void on_nbTxBytes_currentIndexChanged(int index);
void onWidgetRolled(QWidget* widget, bool rollDown); void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p); void onMenuDialogCalled(const QPoint& p);
void tick(); void tick();

View File

@ -395,6 +395,41 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<spacer name="horizontalSpacer_3"> <spacer name="horizontalSpacer_3">
<property name="orientation"> <property name="orientation">

View File

@ -37,6 +37,7 @@ RemoteSinkSettings::RemoteSinkSettings()
void RemoteSinkSettings::resetToDefaults() void RemoteSinkSettings::resetToDefaults()
{ {
m_nbFECBlocks = 0; m_nbFECBlocks = 0;
m_nbTxBytes = 2;
m_dataAddress = "127.0.0.1"; m_dataAddress = "127.0.0.1";
m_dataPort = 9090; m_dataPort = 9090;
m_rgbColor = QColor(140, 4, 4).rgb(); m_rgbColor = QColor(140, 4, 4).rgb();
@ -56,6 +57,7 @@ QByteArray RemoteSinkSettings::serialize() const
{ {
SimpleSerializer s(1); SimpleSerializer s(1);
s.writeU32(1, m_nbFECBlocks); s.writeU32(1, m_nbFECBlocks);
s.writeU32(2, m_nbTxBytes);
s.writeString(3, m_dataAddress); s.writeString(3, m_dataAddress);
s.writeU32(4, m_dataPort); s.writeU32(4, m_dataPort);
s.writeU32(5, m_rgbColor); s.writeU32(5, m_rgbColor);
@ -96,6 +98,7 @@ bool RemoteSinkSettings::deserialize(const QByteArray& data)
m_nbFECBlocks = 0; m_nbFECBlocks = 0;
} }
d.readU32(2, &m_nbTxBytes, 2);
d.readString(3, &m_dataAddress, "127.0.0.1"); d.readString(3, &m_dataAddress, "127.0.0.1");
d.readU32(4, &tmp, 0); d.readU32(4, &tmp, 0);

View File

@ -32,6 +32,7 @@ class Serializable;
struct RemoteSinkSettings struct RemoteSinkSettings
{ {
uint16_t m_nbFECBlocks; uint16_t m_nbFECBlocks;
uint32_t m_nbTxBytes;
QString m_dataAddress; QString m_dataAddress;
uint16_t m_dataPort; uint16_t m_dataPort;
quint32 m_rgbColor; quint32 m_rgbColor;

View File

@ -36,6 +36,7 @@ RemoteSinkSink::RemoteSinkSink() :
m_frequencyOffset(0), m_frequencyOffset(0),
m_basebandSampleRate(48000), m_basebandSampleRate(48000),
m_nbBlocksFEC(0), m_nbBlocksFEC(0),
m_nbTxBytes(SDR_RX_SAMP_SZ <= 16 ? 2 : 4),
m_dataAddress("127.0.0.1"), m_dataAddress("127.0.0.1"),
m_dataPort(9090) m_dataPort(9090)
{ {
@ -68,6 +69,14 @@ void RemoteSinkSink::stopSender()
m_senderThread->wait(); m_senderThread->wait();
} }
void RemoteSinkSink::init()
{
m_dataFrame = nullptr;
m_txBlockIndex = 0;
m_frameCount = 0;
m_sampleIndex = 0;
}
void RemoteSinkSink::setNbBlocksFEC(int nbBlocksFEC) void RemoteSinkSink::setNbBlocksFEC(int nbBlocksFEC)
{ {
qDebug() << "RemoteSinkSink::setNbBlocksFEC: nbBlocksFEC: " << 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_centerFrequency = m_deviceCenterFrequency + m_frequencyOffset;
metaData.m_sampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim); metaData.m_sampleRate = m_basebandSampleRate / (1<<m_settings.m_log2Decim);
metaData.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); metaData.m_sampleBytes = m_nbTxBytes;
metaData.m_sampleBits = SDR_RX_SAMP_SZ; metaData.m_sampleBits = getNbSampleBits();
metaData.m_nbOriginalBlocks = RemoteNbOrginalBlocks; metaData.m_nbOriginalBlocks = RemoteNbOrginalBlocks;
metaData.m_nbFECBlocks = m_nbBlocksFEC; metaData.m_nbFECBlocks = m_nbBlocksFEC;
metaData.m_tv_sec = nowus / 1000000UL; // tv.tv_sec; 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.init();
superBlock.m_header.m_frameIndex = m_frameCount; superBlock.m_header.m_frameIndex = m_frameCount;
superBlock.m_header.m_blockIndex = m_txBlockIndex; superBlock.m_header.m_blockIndex = m_txBlockIndex;
superBlock.m_header.m_sampleBytes = (SDR_RX_SAMP_SZ <= 16 ? 2 : 4); superBlock.m_header.m_sampleBytes = m_nbTxBytes;
superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; superBlock.m_header.m_sampleBits = getNbSampleBits();
RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &superBlock.m_protectedBlock; RemoteMetaDataFEC *destMeta = (RemoteMetaDataFEC *) &superBlock.m_protectedBlock;
*destMeta = metaData; *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 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 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)], convertSampleToData(begin + inSamplesIndex, inRemainingSamples, false);
(const void *) &(*(begin+inSamplesIndex)), // memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)],
inRemainingSamples * sizeof(Sample)); // (const void *) &(*(begin+inSamplesIndex)),
// inRemainingSamples * sizeof(Sample));
m_sampleIndex += inRemainingSamples; m_sampleIndex += inRemainingSamples;
it = end; // all input samples are consumed it = end; // all input samples are consumed
} }
else // complete super block and initiate the next if not end of frame else // complete super block and initiate the next if not end of frame
{ {
memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)], convertSampleToData(begin + inSamplesIndex, samplesPerBlock - m_sampleIndex, false);
(const void *) &(*(begin+inSamplesIndex)), // memcpy((void *) &m_superBlock.m_protectedBlock.buf[m_sampleIndex*sizeof(Sample)],
(samplesPerBlock - m_sampleIndex) * sizeof(Sample)); // (const void *) &(*(begin+inSamplesIndex)),
// (samplesPerBlock - m_sampleIndex) * sizeof(Sample));
it += samplesPerBlock - m_sampleIndex; it += samplesPerBlock - m_sampleIndex;
m_sampleIndex = 0; m_sampleIndex = 0;
m_superBlock.m_header.m_frameIndex = m_frameCount; m_superBlock.m_header.m_frameIndex = m_frameCount;
m_superBlock.m_header.m_blockIndex = m_txBlockIndex; 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_sampleBytes = m_nbTxBytes;
m_superBlock.m_header.m_sampleBits = SDR_RX_SAMP_SZ; m_superBlock.m_header.m_sampleBits = getNbSampleBits();
m_dataFrame->m_superBlocks[m_txBlockIndex] = m_superBlock; m_dataFrame->m_superBlocks[m_txBlockIndex] = m_superBlock;
if (m_txBlockIndex == RemoteNbOrginalBlocks - 1) // frame complete 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); double shiftFactor = HBFilterChainConverter::getShiftFactor(m_settings.m_log2Decim, m_settings.m_filterChainHash);
m_frequencyOffset = round(shiftFactor*m_basebandSampleRate); 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;
}
}

View File

@ -40,7 +40,9 @@ public:
void startSender(); void startSender();
void stopSender(); void stopSender();
void init();
void setNbTxBytes(uint32_t nbTxBytes) { m_nbTxBytes = nbTxBytes; }
void applySettings(const RemoteSinkSettings& settings, bool force = false); void applySettings(const RemoteSinkSettings& settings, bool force = false);
void applyBasebandSampleRate(uint32_t sampleRate); void applyBasebandSampleRate(uint32_t sampleRate);
void setDeviceCenterFrequency(uint64_t frequency) { m_deviceCenterFrequency = frequency; } void setDeviceCenterFrequency(uint64_t frequency) { m_deviceCenterFrequency = frequency; }
@ -61,10 +63,78 @@ private:
int64_t m_frequencyOffset; int64_t m_frequencyOffset;
uint32_t m_basebandSampleRate; uint32_t m_basebandSampleRate;
int m_nbBlocksFEC; int m_nbBlocksFEC;
uint32_t m_nbTxBytes;
QString m_dataAddress; QString m_dataAddress;
uint16_t m_dataPort; uint16_t m_dataPort;
void setNbBlocksFEC(int nbBlocksFEC); 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_ #endif // INCLUDE_REMOTESINKSINK_H_

View File

@ -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. 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> <h3>7: Forward Error Correction setting and status</h3>
![SDR Remote output FEC GUI](../../../doc/img/RemoteOutput_plugin_06.png) ![SDR Remote output FEC GUI](../../../doc/img/RemoteOutput_plugin_06.png)

View File

@ -35,7 +35,6 @@ UDPSinkFEC::UDPSinkFEC() :
m_txDelayRatio(0.0), m_txDelayRatio(0.0),
m_dataFrame(nullptr), m_dataFrame(nullptr),
m_txBlockIndex(0), m_txBlockIndex(0),
m_txBlocksIndex(0),
m_frameCount(0), m_frameCount(0),
m_sampleIndex(0), m_sampleIndex(0),
m_remoteOutputSender(nullptr), m_remoteOutputSender(nullptr),
@ -61,7 +60,6 @@ void UDPSinkFEC::init()
{ {
m_dataFrame = nullptr; m_dataFrame = nullptr;
m_txBlockIndex = 0; m_txBlockIndex = 0;
m_txBlocksIndex = 0;
m_frameCount = 0; m_frameCount = 0;
m_sampleIndex = 0; m_sampleIndex = 0;
} }

View File

@ -92,7 +92,6 @@ private:
RemoteDataFrame *m_dataFrame; RemoteDataFrame *m_dataFrame;
RemoteSuperBlock m_superBlock; //!< current super block being built RemoteSuperBlock m_superBlock; //!< current super block being built
int m_txBlockIndex; //!< Current index in blocks to transmit in the Tx row 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 uint16_t m_frameCount; //!< transmission frame count
int m_sampleIndex; //!< Current sample index in protected block data int m_sampleIndex; //!< Current sample index in protected block data

View File

@ -326,7 +326,50 @@ void RemoteInputUDPHandler::tick()
const RemoteMetaDataFEC& metaData = m_remoteInputBuffer.getCurrentMeta(); const RemoteMetaDataFEC& metaData = m_remoteInputBuffer.getCurrentMeta();
m_readLength = m_readLengthSamples * (metaData.m_sampleBytes & 0xF) * 2; 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) if (m_readLengthSamples > (int) m_converterBufferNbSamples)
{ {
@ -339,14 +382,14 @@ void RemoteInputUDPHandler::tick()
for (int is = 0; is < m_readLengthSamples; is++) for (int is = 0; is < m_readLengthSamples; is++)
{ {
m_converterBuffer[2*is] = ((int16_t*)buf)[2*is]; // I 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] = ((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)); 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) if (m_readLengthSamples > (int) m_converterBufferNbSamples)
{ {
@ -359,23 +402,67 @@ void RemoteInputUDPHandler::tick()
for (int is = 0; is < m_readLengthSamples; is++) for (int is = 0; is < m_readLengthSamples; is++)
{ {
m_converterBuffer[is] = ((int32_t *)buf)[2*is+1]>>8; // Q -> MSB 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_converterBuffer[is] += ((int32_t *)buf)[2*is]>>8; // I -> LSB
} }
m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample)); 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 else // invalid size
{ {
qWarning("RemoteInputUDPHandler::tick: unexpected sample size in stream: %d bits", (int) metaData.m_sampleBits); 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) if (m_tickCount < m_rateDivider)
{ {
m_tickCount++; m_tickCount++;

View File

@ -9864,7 +9864,8 @@ margin-bottom: 20px;
"type" : "integer" "type" : "integer"
}, },
"nbTxBytes" : { "nbTxBytes" : {
"type" : "integer" "type" : "integer",
"description" : "Number of bytes in a transmited I or Q sample\n * 1\n * 2\n * 4\n"
}, },
"apiAddress" : { "apiAddress" : {
"type" : "string" "type" : "string"
@ -9906,6 +9907,10 @@ margin-bottom: 20px;
"type" : "integer", "type" : "integer",
"description" : "Number of FEC blocks per frame" "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" : { "dataAddress" : {
"type" : "string", "type" : "string",
"description" : "Receiving USB data address" "description" : "Receiving USB data address"
@ -51625,7 +51630,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2021-12-18T22:54:13.645+01:00 Generated 2021-12-19T12:04:51.409+01:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -5,6 +5,11 @@ RemoteOutputSettings:
type: integer type: integer
nbTxBytes: nbTxBytes:
type: integer type: integer
description: >
Number of bytes in a transmited I or Q sample
* 1
* 2
* 4
apiAddress: apiAddress:
type: string type: string
apiPort: apiPort:

View File

@ -4,6 +4,13 @@ RemoteSinkSettings:
nbFECBlocks: nbFECBlocks:
description: "Number of FEC blocks per frame" description: "Number of FEC blocks per frame"
type: integer type: integer
nbTxBytes:
type: integer
description: >
Number of bytes in a transmited I or Q sample
* 1
* 2
* 4
dataAddress: dataAddress:
description: "Receiving USB data address" description: "Receiving USB data address"
type: string type: string

View File

@ -5,6 +5,11 @@ RemoteOutputSettings:
type: integer type: integer
nbTxBytes: nbTxBytes:
type: integer type: integer
description: >
Number of bytes in a transmited I or Q sample
* 1
* 2
* 4
apiAddress: apiAddress:
type: string type: string
apiPort: apiPort:

View File

@ -4,6 +4,13 @@ RemoteSinkSettings:
nbFECBlocks: nbFECBlocks:
description: "Number of FEC blocks per frame" description: "Number of FEC blocks per frame"
type: integer type: integer
nbTxBytes:
type: integer
description: >
Number of bytes in a transmited I or Q sample
* 1
* 2
* 4
dataAddress: dataAddress:
description: "Receiving USB data address" description: "Receiving USB data address"
type: string type: string

View File

@ -9864,7 +9864,8 @@ margin-bottom: 20px;
"type" : "integer" "type" : "integer"
}, },
"nbTxBytes" : { "nbTxBytes" : {
"type" : "integer" "type" : "integer",
"description" : "Number of bytes in a transmited I or Q sample\n * 1\n * 2\n * 4\n"
}, },
"apiAddress" : { "apiAddress" : {
"type" : "string" "type" : "string"
@ -9906,6 +9907,10 @@ margin-bottom: 20px;
"type" : "integer", "type" : "integer",
"description" : "Number of FEC blocks per frame" "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" : { "dataAddress" : {
"type" : "string", "type" : "string",
"description" : "Receiving USB data address" "description" : "Receiving USB data address"
@ -51625,7 +51630,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2021-12-18T22:54:13.645+01:00 Generated 2021-12-19T12:04:51.409+01:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -30,6 +30,8 @@ SWGRemoteSinkSettings::SWGRemoteSinkSettings(QString* json) {
SWGRemoteSinkSettings::SWGRemoteSinkSettings() { SWGRemoteSinkSettings::SWGRemoteSinkSettings() {
nb_fec_blocks = 0; nb_fec_blocks = 0;
m_nb_fec_blocks_isSet = false; m_nb_fec_blocks_isSet = false;
nb_tx_bytes = 0;
m_nb_tx_bytes_isSet = false;
data_address = nullptr; data_address = nullptr;
m_data_address_isSet = false; m_data_address_isSet = false;
data_port = 0; data_port = 0;
@ -66,6 +68,8 @@ void
SWGRemoteSinkSettings::init() { SWGRemoteSinkSettings::init() {
nb_fec_blocks = 0; nb_fec_blocks = 0;
m_nb_fec_blocks_isSet = false; m_nb_fec_blocks_isSet = false;
nb_tx_bytes = 0;
m_nb_tx_bytes_isSet = false;
data_address = new QString(""); data_address = new QString("");
m_data_address_isSet = false; m_data_address_isSet = false;
data_port = 0; data_port = 0;
@ -97,6 +101,7 @@ SWGRemoteSinkSettings::init() {
void void
SWGRemoteSinkSettings::cleanup() { SWGRemoteSinkSettings::cleanup() {
if(data_address != nullptr) { if(data_address != nullptr) {
delete data_address; delete data_address;
} }
@ -133,6 +138,8 @@ void
SWGRemoteSinkSettings::fromJsonObject(QJsonObject &pJson) { SWGRemoteSinkSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&nb_fec_blocks, pJson["nbFECBlocks"], "qint32", ""); ::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_address, pJson["dataAddress"], "QString", "QString");
::SWGSDRangel::setValue(&data_port, pJson["dataPort"], "qint32", ""); ::SWGSDRangel::setValue(&data_port, pJson["dataPort"], "qint32", "");
@ -178,6 +185,9 @@ SWGRemoteSinkSettings::asJsonObject() {
if(m_nb_fec_blocks_isSet){ if(m_nb_fec_blocks_isSet){
obj->insert("nbFECBlocks", QJsonValue(nb_fec_blocks)); 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("")){ if(data_address != nullptr && *data_address != QString("")){
toJsonValue(QString("dataAddress"), data_address, obj, QString("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; 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* QString*
SWGRemoteSinkSettings::getDataAddress() { SWGRemoteSinkSettings::getDataAddress() {
return data_address; return data_address;
@ -369,6 +389,9 @@ SWGRemoteSinkSettings::isSet(){
if(m_nb_fec_blocks_isSet){ if(m_nb_fec_blocks_isSet){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_nb_tx_bytes_isSet){
isObjectUpdated = true; break;
}
if(data_address && *data_address != QString("")){ if(data_address && *data_address != QString("")){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }

View File

@ -46,6 +46,9 @@ public:
qint32 getNbFecBlocks(); qint32 getNbFecBlocks();
void setNbFecBlocks(qint32 nb_fec_blocks); void setNbFecBlocks(qint32 nb_fec_blocks);
qint32 getNbTxBytes();
void setNbTxBytes(qint32 nb_tx_bytes);
QString* getDataAddress(); QString* getDataAddress();
void setDataAddress(QString* data_address); void setDataAddress(QString* data_address);
@ -92,6 +95,9 @@ private:
qint32 nb_fec_blocks; qint32 nb_fec_blocks;
bool m_nb_fec_blocks_isSet; bool m_nb_fec_blocks_isSet;
qint32 nb_tx_bytes;
bool m_nb_tx_bytes_isSet;
QString* data_address; QString* data_address;
bool m_data_address_isSet; bool m_data_address_isSet;