mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-21 23:55:13 -05:00
Compare commits
3 Commits
78be244dc6
...
9278b12e25
Author | SHA1 | Date | |
---|---|---|---|
|
9278b12e25 | ||
|
6cc1616cb8 | ||
|
316e635466 |
Binary file not shown.
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 36 KiB |
Binary file not shown.
@ -53,7 +53,7 @@ void RemoteSourceSource::pull(SampleVector::iterator begin, unsigned int nbSampl
|
||||
|
||||
void RemoteSourceSource::pullOne(Sample& sample)
|
||||
{
|
||||
m_dataReadQueue.readSample(sample, true); // true is scale for Tx
|
||||
m_dataReadQueue.readSample(sample, true);
|
||||
}
|
||||
|
||||
void RemoteSourceSource::start()
|
||||
|
@ -279,7 +279,7 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool forc
|
||||
|
||||
if (force || (m_settings.m_dataAddress != settings.m_dataAddress) || (m_settings.m_dataPort != settings.m_dataPort))
|
||||
{
|
||||
if (m_remoteOutputWorker != 0) {
|
||||
if (m_remoteOutputWorker) {
|
||||
m_remoteOutputWorker->setDataAddress(settings.m_dataAddress, settings.m_dataPort);
|
||||
}
|
||||
}
|
||||
@ -288,15 +288,28 @@ void RemoteOutput::applySettings(const RemoteOutputSettings& settings, bool forc
|
||||
{
|
||||
reverseAPIKeys.append("nbFECBlocks");
|
||||
|
||||
if (m_remoteOutputWorker != 0) {
|
||||
if (m_remoteOutputWorker) {
|
||||
m_remoteOutputWorker->setNbBlocksFEC(settings.m_nbFECBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
if (force || (m_settings.m_nbTxBytes != settings.m_nbTxBytes))
|
||||
{
|
||||
reverseAPIKeys.append("nbTxBytes");
|
||||
|
||||
if (m_remoteOutputWorker)
|
||||
{
|
||||
stopWorker();
|
||||
m_remoteOutputWorker->setNbTxBytes(settings.m_nbTxBytes);
|
||||
startWorker();
|
||||
}
|
||||
}
|
||||
|
||||
mutexLocker.unlock();
|
||||
|
||||
qDebug() << "RemoteOutput::applySettings:"
|
||||
<< " m_nbFECBlocks: " << settings.m_nbFECBlocks
|
||||
<< " m_nbTxBytes: " << settings.m_nbTxBytes
|
||||
<< " m_apiAddress: " << settings.m_apiAddress
|
||||
<< " m_apiPort: " << settings.m_apiPort
|
||||
<< " m_dataAddress: " << settings.m_dataAddress
|
||||
@ -404,6 +417,9 @@ void RemoteOutput::webapiUpdateDeviceSettings(
|
||||
if (deviceSettingsKeys.contains("nbFECBlocks")) {
|
||||
settings.m_nbFECBlocks = response.getRemoteOutputSettings()->getNbFecBlocks();
|
||||
}
|
||||
if (deviceSettingsKeys.contains("nbTxBytes")) {
|
||||
settings.m_nbTxBytes = response.getRemoteOutputSettings()->getNbTxBytes();
|
||||
}
|
||||
if (deviceSettingsKeys.contains("apiAddress")) {
|
||||
settings.m_apiAddress = *response.getRemoteOutputSettings()->getApiAddress();
|
||||
}
|
||||
@ -450,6 +466,7 @@ int RemoteOutput::webapiReportGet(
|
||||
void RemoteOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const RemoteOutputSettings& settings)
|
||||
{
|
||||
response.getRemoteOutputSettings()->setNbFecBlocks(settings.m_nbFECBlocks);
|
||||
response.getRemoteOutputSettings()->setNbTxBytes(settings.m_nbTxBytes);
|
||||
response.getRemoteOutputSettings()->setApiAddress(new QString(settings.m_apiAddress));
|
||||
response.getRemoteOutputSettings()->setApiPort(settings.m_apiPort);
|
||||
response.getRemoteOutputSettings()->setDataAddress(new QString(settings.m_dataAddress));
|
||||
@ -657,6 +674,9 @@ void RemoteOutput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys,
|
||||
if (deviceSettingsKeys.contains("nbFECBlocks") || force) {
|
||||
swgRemoteOutputSettings->setNbFecBlocks(settings.m_nbFECBlocks);
|
||||
}
|
||||
if (deviceSettingsKeys.contains("nbTxBytes") || force) {
|
||||
swgRemoteOutputSettings->setNbTxBytes(settings.m_nbTxBytes);
|
||||
}
|
||||
if (deviceSettingsKeys.contains("apiAddress") || force) {
|
||||
swgRemoteOutputSettings->setApiAddress(new QString(settings.m_apiAddress));
|
||||
}
|
||||
|
@ -212,6 +212,7 @@ void RemoteOutputSinkGui::displaySettings()
|
||||
blockApplySettings(true);
|
||||
ui->centerFrequency->setText(QString("%L1").arg(m_deviceCenterFrequency));
|
||||
ui->nbFECBlocks->setValue(m_settings.m_nbFECBlocks);
|
||||
ui->nbTxBytes->setCurrentIndex(log2(m_settings.m_nbTxBytes));
|
||||
|
||||
QString s0 = QString::number(128 + m_settings.m_nbFECBlocks, 'f', 0);
|
||||
QString s1 = QString::number(m_settings.m_nbFECBlocks, 'f', 0);
|
||||
@ -310,6 +311,12 @@ void RemoteOutputSinkGui::on_channelIndex_returnPressed()
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void RemoteOutputSinkGui::on_nbTxBytes_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_nbTxBytes = 1 << index;
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void RemoteOutputSinkGui::on_apiAddress_returnPressed()
|
||||
{
|
||||
m_settings.m_apiAddress = ui->apiAddress->text();
|
||||
|
@ -129,6 +129,7 @@ private slots:
|
||||
void on_nbFECBlocks_valueChanged(int value);
|
||||
void on_deviceIndex_returnPressed();
|
||||
void on_channelIndex_returnPressed();
|
||||
void on_nbTxBytes_currentIndexChanged(int index);
|
||||
void on_apiAddress_returnPressed();
|
||||
void on_apiPort_returnPressed();
|
||||
void on_dataAddress_returnPressed();
|
||||
|
@ -239,6 +239,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">
|
||||
<property name="orientation">
|
||||
|
@ -26,6 +26,7 @@ RemoteOutputSettings::RemoteOutputSettings()
|
||||
void RemoteOutputSettings::resetToDefaults()
|
||||
{
|
||||
m_nbFECBlocks = 0;
|
||||
m_nbTxBytes = 2;
|
||||
m_apiAddress = "127.0.0.1";
|
||||
m_apiPort = 9091;
|
||||
m_dataAddress = "127.0.0.1";
|
||||
@ -42,6 +43,7 @@ QByteArray RemoteOutputSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
|
||||
s.writeU32(3, m_nbTxBytes);
|
||||
s.writeU32(4, m_nbFECBlocks);
|
||||
s.writeString(5, m_apiAddress);
|
||||
s.writeU32(6, m_apiPort);
|
||||
@ -71,6 +73,7 @@ bool RemoteOutputSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
quint32 uintval;
|
||||
|
||||
d.readU32(4, &m_nbTxBytes, 2);
|
||||
d.readU32(4, &m_nbFECBlocks, 0);
|
||||
d.readString(5, &m_apiAddress, "127.0.0.1");
|
||||
d.readU32(6, &uintval, 9090);
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
struct RemoteOutputSettings {
|
||||
quint32 m_nbFECBlocks;
|
||||
quint32 m_nbTxBytes;
|
||||
QString m_apiAddress;
|
||||
quint16 m_apiPort;
|
||||
QString m_dataAddress;
|
||||
|
@ -48,6 +48,7 @@ RemoteOutputWorker::~RemoteOutputWorker()
|
||||
void RemoteOutputWorker::startWork()
|
||||
{
|
||||
qDebug() << "RemoteOutputWorker::startWork: ";
|
||||
m_udpSinkFEC.init();
|
||||
m_udpSinkFEC.startSender();
|
||||
m_maxThrottlems = 0;
|
||||
m_running = true;
|
||||
@ -126,14 +127,14 @@ void RemoteOutputWorker::tick()
|
||||
{
|
||||
SampleVector::iterator beginRead = data.begin() + iPart1Begin;
|
||||
unsigned int partSize = iPart1End - iPart1Begin;
|
||||
m_udpSinkFEC.write(beginRead, partSize);
|
||||
m_udpSinkFEC.write(beginRead, partSize, true);
|
||||
}
|
||||
|
||||
if (iPart2Begin != iPart2End)
|
||||
{
|
||||
SampleVector::iterator beginRead = data.begin() + iPart2Begin;
|
||||
unsigned int partSize = iPart2End - iPart2Begin;
|
||||
m_udpSinkFEC.write(beginRead, partSize);
|
||||
m_udpSinkFEC.write(beginRead, partSize, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
|
||||
void setSamplerate(int samplerate);
|
||||
void setNbBlocksFEC(uint32_t nbBlocksFEC) { m_udpSinkFEC.setNbBlocksFEC(nbBlocksFEC); };
|
||||
void setNbTxBytes(uint32_t nbTxBytes) { m_udpSinkFEC.setNbTxBytes(nbTxBytes); };
|
||||
void setDataAddress(const QString& address, uint16_t port) { m_udpSinkFEC.setRemoteAddress(address, port); }
|
||||
|
||||
bool isRunning() const { return m_running; }
|
||||
|
@ -31,6 +31,7 @@ UDPSinkFEC::UDPSinkFEC() :
|
||||
m_sampleRate(48000),
|
||||
m_nbSamples(0),
|
||||
m_nbBlocksFEC(0),
|
||||
m_nbTxBytes(2),
|
||||
m_txDelayRatio(0.0),
|
||||
m_dataFrame(nullptr),
|
||||
m_txBlockIndex(0),
|
||||
@ -56,6 +57,15 @@ UDPSinkFEC::~UDPSinkFEC()
|
||||
delete m_senderThread;
|
||||
}
|
||||
|
||||
void UDPSinkFEC::init()
|
||||
{
|
||||
m_dataFrame = nullptr;
|
||||
m_txBlockIndex = 0;
|
||||
m_txBlocksIndex = 0;
|
||||
m_frameCount = 0;
|
||||
m_sampleIndex = 0;
|
||||
}
|
||||
|
||||
void UDPSinkFEC::startSender()
|
||||
{
|
||||
qDebug("UDPSinkFEC::startSender");
|
||||
@ -90,7 +100,7 @@ void UDPSinkFEC::setRemoteAddress(const QString& address, uint16_t port)
|
||||
m_remoteOutputSender->setDestination(m_remoteAddress, m_remotePort);
|
||||
}
|
||||
|
||||
void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunkSize)
|
||||
void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunkSize, bool isTx)
|
||||
{
|
||||
const SampleVector::iterator end = begin + sampleChunkSize;
|
||||
|
||||
@ -108,8 +118,8 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
|
||||
|
||||
metaData.m_centerFrequency = 0; // frequency not set by stream
|
||||
metaData.m_sampleRate = m_sampleRate;
|
||||
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;
|
||||
@ -126,8 +136,8 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
|
||||
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;
|
||||
@ -151,27 +161,23 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
|
||||
} // block zero
|
||||
|
||||
// handle different sample sizes...
|
||||
int samplesPerBlock = RemoteNbBytesPerBlock / (SDR_RX_SAMP_SZ <= 16 ? 4 : 8); // two I or Q samples
|
||||
int samplesPerBlock = RemoteNbBytesPerBlock / (m_nbTxBytes * 2); // 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, isTx);
|
||||
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, isTx);
|
||||
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
|
||||
@ -196,3 +202,15 @@ void UDPSinkFEC::write(const SampleVector::iterator& begin, uint32_t sampleChunk
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t UDPSinkFEC::getNbSampleBits()
|
||||
{
|
||||
if (m_nbTxBytes == 1) {
|
||||
return 8;
|
||||
} else if (m_nbTxBytes == 2) {
|
||||
return 16;
|
||||
} else if (m_nbTxBytes == 4) {
|
||||
return 24;
|
||||
} else {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
@ -47,13 +47,14 @@ public:
|
||||
/** Destroy UDP sink */
|
||||
~UDPSinkFEC();
|
||||
|
||||
void init();
|
||||
void startSender();
|
||||
void stopSender();
|
||||
|
||||
/**
|
||||
* Write IQ samples
|
||||
*/
|
||||
void write(const SampleVector::iterator& begin, uint32_t sampleChunkSize);
|
||||
void write(const SampleVector::iterator& begin, uint32_t sampleChunkSize, bool isTx);
|
||||
|
||||
/** Return the last error, or return an empty string if there is no error. */
|
||||
std::string error()
|
||||
@ -67,6 +68,7 @@ public:
|
||||
void setSampleRate(uint32_t sampleRate);
|
||||
|
||||
void setNbBlocksFEC(uint32_t nbBlocksFEC);
|
||||
void setNbTxBytes(uint32_t nbTxBytes) { m_nbTxBytes = nbTxBytes; }
|
||||
void setRemoteAddress(const QString& address, uint16_t port);
|
||||
|
||||
/** Return true if the stream is OK, return false if there is an error. */
|
||||
@ -85,6 +87,7 @@ private:
|
||||
CRC64 m_crc64;
|
||||
RemoteMetaDataFEC m_currentMetaFEC; //!< Meta data for current frame
|
||||
uint32_t m_nbBlocksFEC; //!< Variable number of FEC blocks
|
||||
uint32_t m_nbTxBytes;
|
||||
float m_txDelayRatio; //!< Delay in ratio of nominal frame period
|
||||
RemoteDataFrame *m_dataFrame;
|
||||
RemoteSuperBlock m_superBlock; //!< current super block being built
|
||||
@ -97,6 +100,74 @@ private:
|
||||
QThread *m_senderThread;
|
||||
QString m_remoteAddress;
|
||||
uint16_t m_remotePort;
|
||||
|
||||
uint32_t getNbSampleBits();
|
||||
|
||||
inline void convertSampleToData(const SampleVector::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 /* PLUGINS_SAMPLESINK_REMOTEOUTPUT_UDPSINKFEC_H_ */
|
||||
|
@ -77,7 +77,7 @@ void RemoteDataReadQueue::setSize(uint32_t size)
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
|
||||
void RemoteDataReadQueue::readSample(Sample& s, bool isTx)
|
||||
{
|
||||
// depletion/repletion state
|
||||
if (m_dataFrame == nullptr)
|
||||
@ -89,7 +89,7 @@ void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
|
||||
qDebug("RemoteDataReadQueue::readSample: initial pop new frame: queue size: %u", length());
|
||||
m_blockIndex = 1;
|
||||
m_sampleIndex = 0;
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx);
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, isTx);
|
||||
m_sampleIndex++;
|
||||
}
|
||||
else
|
||||
@ -107,7 +107,7 @@ void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
|
||||
|
||||
if (m_sampleIndex < samplesPerBlock)
|
||||
{
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx);
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, isTx);
|
||||
m_sampleIndex++;
|
||||
m_sampleCount++;
|
||||
}
|
||||
@ -118,7 +118,7 @@ void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
|
||||
|
||||
if (m_blockIndex < RemoteNbOrginalBlocks)
|
||||
{
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx);
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, isTx);
|
||||
m_sampleIndex++;
|
||||
m_sampleCount++;
|
||||
}
|
||||
@ -133,7 +133,7 @@ void RemoteDataReadQueue::readSample(Sample& s, bool scaleForTx)
|
||||
{
|
||||
m_blockIndex = 1;
|
||||
m_sampleIndex = 0;
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, scaleForTx);
|
||||
convertDataToSample(s, m_blockIndex, m_sampleIndex, isTx);
|
||||
m_sampleIndex++;
|
||||
m_sampleCount++;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
~RemoteDataReadQueue();
|
||||
|
||||
void push(RemoteDataFrame* dataFrame); //!< push frame on the queue
|
||||
void readSample(Sample& s, bool scaleForTx = false); //!< Read sample from queue possibly scaling to Tx size
|
||||
void readSample(Sample& s, bool isTx); //!< Read sample from queue
|
||||
uint32_t length() const { return m_dataReadQueue.size(); } //!< Returns queue length
|
||||
uint32_t size() const { return m_maxSize; } //!< Returns queue size (max length)
|
||||
void setSize(uint32_t size); //!< Sets the queue size (max length)
|
||||
@ -57,37 +57,74 @@ private:
|
||||
|
||||
RemoteDataFrame* pop(); //!< Pop frame from the queue
|
||||
|
||||
inline void convertDataToSample(Sample& s, uint32_t blockIndex, uint32_t sampleIndex, bool scaleForTx)
|
||||
inline void convertDataToSample(Sample& s, uint32_t blockIndex, uint32_t sampleIndex, bool isTx)
|
||||
{
|
||||
int sampleSize = m_dataFrame->m_superBlocks[blockIndex].m_header.m_sampleBytes * 2; // I/Q sample size in data block
|
||||
int samplebits = m_dataFrame->m_superBlocks[blockIndex].m_header.m_sampleBits; // I or Q sample size in bits
|
||||
int32_t iconv, qconv;
|
||||
|
||||
if ((sizeof(Sample) == 4) && (sampleSize == 8)) // generally 24->16 bits
|
||||
{
|
||||
iconv = ((int32_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0];
|
||||
qconv = ((int32_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+4]))[0];
|
||||
iconv >>= scaleForTx ? (SDR_TX_SAMP_SZ-SDR_RX_SAMP_SZ) : (samplebits-SDR_RX_SAMP_SZ);
|
||||
qconv >>= scaleForTx ? (SDR_TX_SAMP_SZ-SDR_RX_SAMP_SZ) : (samplebits-SDR_RX_SAMP_SZ);
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else if ((sizeof(Sample) == 8) && (sampleSize == 4)) // generally 16->24 bits
|
||||
{
|
||||
iconv = ((int16_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0];
|
||||
qconv = ((int16_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+2]))[0];
|
||||
iconv <<= scaleForTx ? (SDR_TX_SAMP_SZ-samplebits) : (SDR_RX_SAMP_SZ-samplebits);
|
||||
qconv <<= scaleForTx ? (SDR_TX_SAMP_SZ-samplebits) : (SDR_RX_SAMP_SZ-samplebits);
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else if ((sampleSize == 4) || (sampleSize == 8)) // generally 16->16 or 24->24 bits
|
||||
if (sizeof(Sample) == sampleSize) // no conversion
|
||||
{
|
||||
s = *((Sample*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]));
|
||||
}
|
||||
else // invalid size
|
||||
else if (isTx)
|
||||
{
|
||||
s = Sample{0, 0};
|
||||
if (sampleSize == 2) // 8 -> 16 bits
|
||||
{
|
||||
int8_t iu = m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize];
|
||||
int8_t qu = m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+1];
|
||||
iconv = iu * (1 << 8);
|
||||
qconv = qu * (1 << 8);
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else if (sampleSize == 4) // just convert types (always 16 bits wide)
|
||||
{
|
||||
iconv = ((int16_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0];
|
||||
qconv = ((int16_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+2]))[0];
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else if (sampleSize == 8) // just convert types (always 16 bits wide)
|
||||
{
|
||||
iconv = ((int32_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0];
|
||||
qconv = ((int32_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+4]))[0];
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else // invalid
|
||||
{
|
||||
s = Sample{0, 0};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sampleSize == 2) // 8 -> 16 or 24 bits
|
||||
{
|
||||
int8_t iu = m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize];
|
||||
int8_t qu = m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+1];
|
||||
iconv = iu * (1 << sizeof(Sample)*2);
|
||||
qconv = qu * (1 << sizeof(Sample)*2);
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else if (sampleSize == 4) // 16 -> 24 bits
|
||||
{
|
||||
iconv = ((int16_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0] << 8;
|
||||
qconv = ((int16_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+2]))[0] << 8;
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else if (sampleSize == 8) // 24 -> 16 bits
|
||||
{
|
||||
iconv = ((int32_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize]))[0] >> 8;
|
||||
qconv = ((int32_t*) &(m_dataFrame->m_superBlocks[blockIndex].m_protectedBlock.buf[sampleIndex*sampleSize+4]))[0] >> 8;
|
||||
s.setReal(iconv);
|
||||
s.setImag(qconv);
|
||||
}
|
||||
else // invalid
|
||||
{
|
||||
s = Sample{0, 0};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -9863,6 +9863,9 @@ margin-bottom: 20px;
|
||||
"nbFECBlocks" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"nbTxBytes" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"apiAddress" : {
|
||||
"type" : "string"
|
||||
},
|
||||
@ -51622,7 +51625,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2021-12-15T21:39:08.842+01:00
|
||||
Generated 2021-12-18T22:54:13.645+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,8 @@ RemoteOutputSettings:
|
||||
properties:
|
||||
nbFECBlocks:
|
||||
type: integer
|
||||
nbTxBytes:
|
||||
type: integer
|
||||
apiAddress:
|
||||
type: string
|
||||
apiPort:
|
||||
|
@ -3,6 +3,8 @@ RemoteOutputSettings:
|
||||
properties:
|
||||
nbFECBlocks:
|
||||
type: integer
|
||||
nbTxBytes:
|
||||
type: integer
|
||||
apiAddress:
|
||||
type: string
|
||||
apiPort:
|
||||
|
@ -9863,6 +9863,9 @@ margin-bottom: 20px;
|
||||
"nbFECBlocks" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"nbTxBytes" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"apiAddress" : {
|
||||
"type" : "string"
|
||||
},
|
||||
@ -51622,7 +51625,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2021-12-15T21:39:08.842+01:00
|
||||
Generated 2021-12-18T22:54:13.645+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,6 +30,8 @@ SWGRemoteOutputSettings::SWGRemoteOutputSettings(QString* json) {
|
||||
SWGRemoteOutputSettings::SWGRemoteOutputSettings() {
|
||||
nb_fec_blocks = 0;
|
||||
m_nb_fec_blocks_isSet = false;
|
||||
nb_tx_bytes = 0;
|
||||
m_nb_tx_bytes_isSet = false;
|
||||
api_address = nullptr;
|
||||
m_api_address_isSet = false;
|
||||
api_port = 0;
|
||||
@ -60,6 +62,8 @@ void
|
||||
SWGRemoteOutputSettings::init() {
|
||||
nb_fec_blocks = 0;
|
||||
m_nb_fec_blocks_isSet = false;
|
||||
nb_tx_bytes = 0;
|
||||
m_nb_tx_bytes_isSet = false;
|
||||
api_address = new QString("");
|
||||
m_api_address_isSet = false;
|
||||
api_port = 0;
|
||||
@ -85,6 +89,7 @@ SWGRemoteOutputSettings::init() {
|
||||
void
|
||||
SWGRemoteOutputSettings::cleanup() {
|
||||
|
||||
|
||||
if(api_address != nullptr) {
|
||||
delete api_address;
|
||||
}
|
||||
@ -116,6 +121,8 @@ void
|
||||
SWGRemoteOutputSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&nb_fec_blocks, pJson["nbFECBlocks"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&nb_tx_bytes, pJson["nbTxBytes"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&api_address, pJson["apiAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&api_port, pJson["apiPort"], "qint32", "");
|
||||
@ -155,6 +162,9 @@ SWGRemoteOutputSettings::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(api_address != nullptr && *api_address != QString("")){
|
||||
toJsonValue(QString("apiAddress"), api_address, obj, QString("QString"));
|
||||
}
|
||||
@ -199,6 +209,16 @@ SWGRemoteOutputSettings::setNbFecBlocks(qint32 nb_fec_blocks) {
|
||||
this->m_nb_fec_blocks_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRemoteOutputSettings::getNbTxBytes() {
|
||||
return nb_tx_bytes;
|
||||
}
|
||||
void
|
||||
SWGRemoteOutputSettings::setNbTxBytes(qint32 nb_tx_bytes) {
|
||||
this->nb_tx_bytes = nb_tx_bytes;
|
||||
this->m_nb_tx_bytes_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRemoteOutputSettings::getApiAddress() {
|
||||
return api_address;
|
||||
@ -307,6 +327,9 @@ SWGRemoteOutputSettings::isSet(){
|
||||
if(m_nb_fec_blocks_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_nb_tx_bytes_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(api_address && *api_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -45,6 +45,9 @@ public:
|
||||
qint32 getNbFecBlocks();
|
||||
void setNbFecBlocks(qint32 nb_fec_blocks);
|
||||
|
||||
qint32 getNbTxBytes();
|
||||
void setNbTxBytes(qint32 nb_tx_bytes);
|
||||
|
||||
QString* getApiAddress();
|
||||
void setApiAddress(QString* api_address);
|
||||
|
||||
@ -82,6 +85,9 @@ private:
|
||||
qint32 nb_fec_blocks;
|
||||
bool m_nb_fec_blocks_isSet;
|
||||
|
||||
qint32 nb_tx_bytes;
|
||||
bool m_nb_tx_bytes_isSet;
|
||||
|
||||
QString* api_address;
|
||||
bool m_api_address_isSet;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user