diff --git a/Readme.md b/Readme.md
index d24087302..9c0961140 100644
--- a/Readme.md
+++ b/Readme.md
@@ -81,6 +81,8 @@ If you use your own location for libairspyhf install directory you need to speci
`-DLIBAIRSPYHF_LIBRARIES=/opt/install/libairspyhf/lib/libairspyhf.so -DLIBAIRSPYHF_INCLUDE_DIR=/opt/install/libairspyhf/include`
+It is recommended to add `-DRX_SAMPLE_24BIT` on the cmake command line to activate the Rx 24 bit DSP build and take advantage of improved dynamic range when using decimation.
+
BladeRF
[BladeRF](https://www.nuand.com/) is supported through the libbladerf library that should be installed in your system for proper build of the software and operation support. Add `libbladerf-dev` to the list of dependencies to install.
@@ -160,7 +162,7 @@ If you use your own location for libmirisdr-4 install directory you need to spec
Plugins for special devices
-These plugins do not use any hardware device connected to your system. They support "virtual" devices related to the file system or the network.
+These plugins do not use any hardware device connected to your system.
File input
@@ -176,6 +178,10 @@ The [File sink plugin](https://github.com/f4exb/sdrangel/tree/dev/plugins/sample
Note that this plugin does not require any of the hardware support libraries nor the libusb library. It is always available in the list of devices as `FileSink[0]` even if no physical device is connected.
+Test source
+
+The [Test source plugin](https://github.com/f4exb/sdrangel/tree/master/plugins/samplesource/testsource) is an internal continuous wave generator that can be used to carry out test of software internals.
+
SDRdaemon receiver input
Linux only.
@@ -290,6 +296,15 @@ To be sure you will need at least Qt version 5.5. It definitely does not work wi
- Windows 32 build is made with 5.9.1 and has Qt ANGLE support (OpenGL emulation with DirectX)
- Windows 64 build is made with 5.9.1 and has no Qt ANGLE support (native OpenGL)
+24 bit DSP
+
+By default all Rx DSP processes use 16 bit samples coded on int16 fields. In order to use 24 bit samples coded on int32 fields you can specify `-DRX_SAMPLE_24BIT` on the cmake command line. This will give more dynamic range when the number of bits with decimation exceeds 16 bits:
+
+ - RTL-SDR, HackRF: (8 bit native) no advantage
+ - Funcube Pro and Pro+: (16 bit native) no decimation hence no advantage
+ - Airspy, BladeRF, LimeSDR, PlutoSDR, SDRPlay: (12 bit native) advantage for decimation by 32 or 64
+ - AirspyHF: (16 bit native) advantage for any decimation
+
Ubuntu
Prerequisites for 14.04 LTS
diff --git a/doc/img/UDPsrc_plugin.png b/doc/img/UDPsrc_plugin.png
index fbece5d37..cc4a913cf 100644
Binary files a/doc/img/UDPsrc_plugin.png and b/doc/img/UDPsrc_plugin.png differ
diff --git a/doc/img/UDPsrc_plugin.xcf b/doc/img/UDPsrc_plugin.xcf
index 8ac7a0890..5c6042f25 100644
Binary files a/doc/img/UDPsrc_plugin.xcf and b/doc/img/UDPsrc_plugin.xcf differ
diff --git a/plugins/channelrx/udpsrc/readme.md b/plugins/channelrx/udpsrc/readme.md
index 3515b5352..f26dc0f63 100644
--- a/plugins/channelrx/udpsrc/readme.md
+++ b/plugins/channelrx/udpsrc/readme.md
@@ -36,20 +36,25 @@ The display is in the format `address:audio port/data port`
Sample rate in samples per second of the signal that is sent over UDP. The actual byte rate depends on the type of sample which corresponds to a number of bytes per sample.
-6: Type of samples
+6: Type and size of samples
-Combo box to specify the type of samples that are sent over UDP.
+Left: combo box to specify the type of samples that are sent over UDP:
- - `S16LE I/Q`: Raw I/Q samples on signed 16 bits integers with Little Endian layout. Use it with software that accepts I/Q data as input like GNUradio with the `UDP source` block. The output is interleaved I and Q samples
- - `S16LE NFM`: AF of FM demodulated signal as 16 bits signed integers with Little Endian layout. Use it with software that takes the FM demodulated audio or the discriminator output of a radio as input. Make sure you specify the appropriate signal bandwidth (see 7) according to the AF bandwidth needs. The output is a repetition of NFM samples on real part and on imaginary part this facilitates integration wtih software expecting a stereo type of input with the same samples on L and R channels. With GNURadio just use a complex to real block.
- - `S16LE NFM Mono`: This is the same as above but only one sample is output for one NFM sample. This can be used with software that accept a mono type of input like `dsd` or `multimon`.
- - `S16LE USB`: AF of USB demodulated signal as 16 bits signed integers with Little Endian layout. Use it with software that uses a SSB demodulated signal as input i.e. software that is based on the audio output of a SSB radio. The output is the I/Q binaural output of the demodulator.
- - `S16LE LSB`: AF of LSB demodulated signal as 16 bits signed integers with Little Endian layout. Use it with software that uses a SSB demodulated signal as input i.e. software that is based on the audio output of a SSB radio. The output is the I/Q binaural output of the demodulator.
- - `S16LE LSB Mono`: AF of the LSB part of a SSB demodulated signal as "mono" (I+Q)*0.7 samples that is one sample per demodulator output sample. This can be used with software that accepts mono type of input.
- - `S16LE USB Mono`: AF of the USB part of a SSB demodulated signal as "mono" (I+Q)*0.7 samples that is one sample per demodulator output sample. This can be used with software that accepts mono type of input.
- - `S16LE AM Mono`: AF of the enveloppe demodulated signal i.e. channel magnitude or sqrt(I² + Q²) as "mono" samples that is one sample per demodulator output sample. This can be used with software that accepts mono type of input.
- - `S16LE AM !DC Mono`: Same as above but with a DC block based on magnitude average over a 5 ms period
- - `S16LE AM BPF Mono`: Same as AM Mono but raw magnitude signal is passed through a bandpass filter with lower cutoff at 300 Hz and higher cutoff at RF bandwidth frequency
+ - `I/Q`: Raw I/Q samples. Use it with software that accepts I/Q data as input like GNUradio with the `UDP source` block. The output is interleaved I and Q samples
+ - `NFM`: AF of FM demodulated signal. Use it with software that takes the FM demodulated audio or the discriminator output of a radio as input. Make sure you specify the appropriate signal bandwidth (see 7) according to the AF bandwidth needs. The output is a repetition of NFM samples on real part and on imaginary part this facilitates integration wtih software expecting a stereo type of input with the same samples on L and R channels. With GNURadio just use a complex to real block.
+ - `NFM Mono`: This is the same as above but only one sample is output for one NFM sample. This can be used with software that accept a mono type of input like `dsd` or `multimon`.
+ - `USB`: AF of USB demodulated signal. Use it with software that uses a SSB demodulated signal as input i.e. software that is based on the audio output of a SSB radio. The output is the I/Q binaural output of the demodulator.
+ - `LSB`: AF of LSB demodulated signal. Use it with software that uses a SSB demodulated signal as input i.e. software that is based on the audio output of a SSB radio. The output is the I/Q binaural output of the demodulator.
+ - `LSB Mono`: AF of the LSB part of a SSB demodulated signal as "mono" (I+Q)*0.7 samples that is one sample per demodulator output sample. This can be used with software that accepts mono type of input.
+ - `USB Mono`: AF of the USB part of a SSB demodulated signal as "mono" (I+Q)*0.7 samples that is one sample per demodulator output sample. This can be used with software that accepts mono type of input.
+ - `AM Mono`: AF of the enveloppe demodulated signal i.e. channel magnitude or sqrt(I² + Q²) as "mono" samples that is one sample per demodulator output sample. This can be used with software that accepts mono type of input.
+ - `AM !DC Mono`: Same as above but with a DC block based on magnitude average over a 5 ms period
+ - `AM BPF Mono`: Same as AM Mono but raw magnitude signal is passed through a bandpass filter with lower cutoff at 300 Hz and higher cutoff at RF bandwidth frequency
+
+Right: Sample size in bits:
+
+ - `16 bits`: samples are 16 bit signed with little endian layout (S16LE)
+ - `24 bits`: samples are 32 bit signed with little endian layout (S32LE) using only the 3 less significant bytes. This means that the range is -2²³ to 2²³ - 1
7: Signal bandwidth
diff --git a/plugins/channelrx/udpsrc/udpsrc.cpp b/plugins/channelrx/udpsrc/udpsrc.cpp
index 01b45a35a..b4b41473e 100644
--- a/plugins/channelrx/udpsrc/udpsrc.cpp
+++ b/plugins/channelrx/udpsrc/udpsrc.cpp
@@ -57,8 +57,10 @@ UDPSrc::UDPSrc(DeviceSourceAPI *deviceAPI) :
{
setObjectName(m_channelId);
- m_udpBuffer = new UDPSink(this, udpBlockSize, m_settings.m_udpPort);
- m_udpBufferMono = new UDPSink(this, udpBlockSize, m_settings.m_udpPort);
+ m_udpBuffer16 = new UDPSink(this, udpBlockSize, m_settings.m_udpPort);
+ m_udpBufferMono16 = new UDPSink(this, udpBlockSize, m_settings.m_udpPort);
+ m_udpBuffer24 = new UDPSink(this, udpBlockSize, m_settings.m_udpPort);
+ m_udpBufferMono24 = new UDPSink(this, udpBlockSize, m_settings.m_udpPort);
m_audioSocket = new QUdpSocket(this);
m_udpAudioBuf = new char[m_udpAudioPayloadSize];
@@ -109,8 +111,10 @@ UDPSrc::UDPSrc(DeviceSourceAPI *deviceAPI) :
UDPSrc::~UDPSrc()
{
delete m_audioSocket;
- delete m_udpBuffer;
- delete m_udpBufferMono;
+ delete m_udpBuffer24;
+ delete m_udpBufferMono24;
+ delete m_udpBuffer16;
+ delete m_udpBufferMono16;
delete[] m_udpAudioBuf;
if (UDPFilter) delete UDPFilter;
if (m_settings.m_audioActive) DSPEngine::instance()->removeAudioSink(&m_audioFifo);
@@ -148,7 +152,7 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
if ((m_settings.m_agc) &&
(m_settings.m_sampleFormat != UDPSrcSettings::FormatNFM) &&
(m_settings.m_sampleFormat != UDPSrcSettings::FormatNFMMono) &&
- (m_settings.m_sampleFormat != UDPSrcSettings::FormatS16LE))
+ (m_settings.m_sampleFormat != UDPSrcSettings::FormatIQ))
{
agcFactor = m_agc.feedAndGetValue(ci);
inMagSq = m_agc.getMagSq();
@@ -179,7 +183,7 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
{
l = m_squelchOpen ? sideband[i].real() * m_settings.m_gain : 0;
r = m_squelchOpen ? sideband[i].imag() * m_settings.m_gain : 0;
- m_udpBuffer->write(Sample(l, r));
+ udpWrite(l, r);
m_outMovingAverage.feed((l*l + r*r) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
}
@@ -195,22 +199,24 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
{
l = m_squelchOpen ? sideband[i].real() * m_settings.m_gain : 0;
r = m_squelchOpen ? sideband[i].imag() * m_settings.m_gain : 0;
- m_udpBuffer->write(Sample(l, r));
+ udpWrite(l, r);
m_outMovingAverage.feed((l*l + r*r) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
}
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatNFM)
{
- double demod = m_squelchOpen ? SDR_RX_SCALED * m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain : 0;
- m_udpBuffer->write(Sample(demod, demod));
- m_outMovingAverage.feed((demod * demod) / (SDR_RX_SCALED*SDR_RX_SCALED));
+ Real discri = m_squelchOpen ? m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain : 0;
+ FixReal demod = (FixReal) (SDR_RX_SCALEF * discri);
+ udpWrite(demod, demod);
+ m_outMovingAverage.feed(discri*discri);
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatNFMMono)
{
- FixReal demod = m_squelchOpen ? (FixReal) (SDR_RX_SCALEF * m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain) : 0;
- m_udpBufferMono->write(demod);
- m_outMovingAverage.feed((demod * demod) / SDR_RX_SCALED*SDR_RX_SCALED);
+ Real discri = m_squelchOpen ? m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain : 0;
+ FixReal demod = (FixReal) (SDR_RX_SCALEF * discri);
+ udpWriteMono(demod);
+ m_outMovingAverage.feed(discri*discri);
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatLSBMono) // Monaural LSB
{
@@ -222,7 +228,7 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
for (int i = 0; i < n_out; i++)
{
l = m_squelchOpen ? (sideband[i].real() + sideband[i].imag()) * 0.7 * m_settings.m_gain : 0;
- m_udpBufferMono->write(l);
+ udpWriteMono(l);
m_outMovingAverage.feed((l * l) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
}
@@ -237,16 +243,17 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
for (int i = 0; i < n_out; i++)
{
l = m_squelchOpen ? (sideband[i].real() + sideband[i].imag()) * 0.7 * m_settings.m_gain : 0;
- m_udpBufferMono->write(l);
+ udpWriteMono(l);
m_outMovingAverage.feed((l * l) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
}
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatAMMono)
{
- FixReal demod = m_squelchOpen ? (FixReal) (sqrt(inMagSq) * agcFactor * m_settings.m_gain) : 0;
- m_udpBufferMono->write(demod);
- m_outMovingAverage.feed((demod * demod) / SDR_RX_SCALED*SDR_RX_SCALED);
+ Real amplitude = m_squelchOpen ? sqrt(inMagSq) * agcFactor * m_settings.m_gain : 0;
+ FixReal demod = (FixReal) amplitude;
+ udpWriteMono(demod);
+ m_outMovingAverage.feed((amplitude/SDR_RX_SCALEF)*(amplitude/SDR_RX_SCALEF));
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatAMNoDCMono)
{
@@ -254,13 +261,14 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
{
double demodf = sqrt(inMagSq);
m_amMovingAverage.feed(demodf);
- FixReal demod = (FixReal) ((demodf - m_amMovingAverage.average()) * agcFactor * m_settings.m_gain);
- m_udpBufferMono->write(demod);
- m_outMovingAverage.feed((demod * demod) / SDR_RX_SCALED*SDR_RX_SCALED);
+ Real amplitude = (demodf - m_amMovingAverage.average()) * agcFactor * m_settings.m_gain;
+ FixReal demod = (FixReal) amplitude;
+ udpWriteMono(demod);
+ m_outMovingAverage.feed((amplitude/SDR_RX_SCALEF)*(amplitude/SDR_RX_SCALEF));
}
else
{
- m_udpBufferMono->write(0);
+ udpWriteMono(0);
m_outMovingAverage.feed(0);
}
}
@@ -271,13 +279,14 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
double demodf = sqrt(inMagSq);
demodf = m_bandpass.filter(demodf);
demodf /= 301.0;
- FixReal demod = (FixReal) (demodf * agcFactor * m_settings.m_gain);
- m_udpBufferMono->write(demod);
- m_outMovingAverage.feed((demod * demod) / SDR_RX_SCALED*SDR_RX_SCALED);
+ Real amplitude = demodf * agcFactor * m_settings.m_gain;
+ FixReal demod = (FixReal) amplitude;
+ udpWriteMono(demod);
+ m_outMovingAverage.feed((amplitude/SDR_RX_SCALEF)*(amplitude/SDR_RX_SCALEF));
}
else
{
- m_udpBufferMono->write(0);
+ udpWriteMono(0);
m_outMovingAverage.feed(0);
}
}
@@ -285,14 +294,12 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
{
if (m_squelchOpen)
{
- Sample s(ci.real() * m_settings.m_gain, ci.imag() * m_settings.m_gain);
- m_udpBuffer->write(s);
+ udpWrite(ci.real() * m_settings.m_gain, ci.imag() * m_settings.m_gain);
m_outMovingAverage.feed((inMagSq*m_settings.m_gain*m_settings.m_gain) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
else
{
- Sample s(0, 0);
- m_udpBuffer->write(s);
+ udpWrite(0, 0);
m_outMovingAverage.feed(0);
}
}
@@ -484,6 +491,7 @@ void UDPSrc::applySettings(const UDPSrcSettings& settings, bool force)
<< " m_squelchGate" << settings.m_squelchGate
<< " m_agc" << settings.m_agc
<< " m_sampleFormat: " << settings.m_sampleFormat
+ << " m_sampleSize: " << 16 + settings.m_sampleSize*8
<< " m_outputSampleRate: " << settings.m_outputSampleRate
<< " m_rfBandwidth: " << settings.m_rfBandwidth
<< " m_fmDeviation: " << settings.m_fmDeviation
@@ -568,14 +576,18 @@ void UDPSrc::applySettings(const UDPSrcSettings& settings, bool force)
if ((settings.m_udpAddress != m_settings.m_udpAddress) || force)
{
- m_udpBuffer->setAddress(const_cast(settings.m_udpAddress));
- m_udpBufferMono->setAddress(const_cast(settings.m_udpAddress));
+ m_udpBuffer16->setAddress(const_cast(settings.m_udpAddress));
+ m_udpBufferMono16->setAddress(const_cast(settings.m_udpAddress));
+ m_udpBuffer24->setAddress(const_cast(settings.m_udpAddress));
+ m_udpBufferMono24->setAddress(const_cast(settings.m_udpAddress));
}
if ((settings.m_udpPort != m_settings.m_udpPort) || force)
{
- m_udpBuffer->setPort(settings.m_udpPort);
- m_udpBufferMono->setPort(settings.m_udpPort);
+ m_udpBuffer16->setPort(settings.m_udpPort);
+ m_udpBufferMono16->setPort(settings.m_udpPort);
+ m_udpBuffer24->setPort(settings.m_udpPort);
+ m_udpBufferMono24->setPort(settings.m_udpPort);
}
if ((settings.m_audioPort != m_settings.m_audioPort) || force)
diff --git a/plugins/channelrx/udpsrc/udpsrc.h b/plugins/channelrx/udpsrc/udpsrc.h
index f575443e3..3dcc65b70 100644
--- a/plugins/channelrx/udpsrc/udpsrc.h
+++ b/plugins/channelrx/udpsrc/udpsrc.h
@@ -142,6 +142,22 @@ protected:
{ }
};
+ struct Sample16
+ {
+ Sample16() : m_r(0), m_i(0) {}
+ Sample16(int16_t r, int16_t i) : m_r(r), m_i(i) {}
+ int16_t m_r;
+ int16_t m_i;
+ };
+
+ struct Sample24
+ {
+ Sample24() : m_r(0), m_i(0) {}
+ Sample24(int32_t r, int32_t i) : m_r(r), m_i(i) {}
+ int32_t m_r;
+ int32_t m_i;
+ };
+
DeviceSourceAPI *m_deviceAPI;
ThreadedBasebandSampleSink* m_threadedChannelizer;
DownChannelizer* m_channelizer;
@@ -167,8 +183,10 @@ protected:
fftfilt* UDPFilter;
SampleVector m_sampleBuffer;
- UDPSink *m_udpBuffer;
- UDPSink *m_udpBufferMono;
+ UDPSink *m_udpBuffer16;
+ UDPSink *m_udpBufferMono16;
+ UDPSink *m_udpBuffer24;
+ UDPSink *m_udpBufferMono24;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
@@ -259,6 +277,46 @@ protected:
}
}
+ void udpWrite(FixReal real, FixReal imag)
+ {
+ if (SDR_RX_SAMP_SZ == 16)
+ {
+ if (m_settings.m_sampleSize == UDPSrcSettings::Size16bits) {
+ m_udpBuffer16->write(Sample16(real, imag));
+ } else if (m_settings.m_sampleSize == UDPSrcSettings::Size24bits) {
+ m_udpBuffer24->write(Sample24(real<<8, imag<<8));
+ }
+ }
+ else if (SDR_RX_SAMP_SZ == 24)
+ {
+ if (m_settings.m_sampleSize == UDPSrcSettings::Size16bits) {
+ m_udpBuffer16->write(Sample16(real>>8, imag>>8));
+ } else if (m_settings.m_sampleSize == UDPSrcSettings::Size24bits) {
+ m_udpBuffer24->write(Sample24(real, imag));
+ }
+ }
+ }
+
+ void udpWriteMono(FixReal sample)
+ {
+ if (SDR_RX_SAMP_SZ == 16)
+ {
+ if (m_settings.m_sampleSize == UDPSrcSettings::Size16bits) {
+ m_udpBufferMono16->write(sample);
+ } else if (m_settings.m_sampleSize == UDPSrcSettings::Size24bits) {
+ m_udpBufferMono24->write(sample<<8);
+ }
+ }
+ else if (SDR_RX_SAMP_SZ == 24)
+ {
+ if (m_settings.m_sampleSize == UDPSrcSettings::Size16bits) {
+ m_udpBufferMono16->write(sample>>8);
+ } else if (m_settings.m_sampleSize == UDPSrcSettings::Size24bits) {
+ m_udpBufferMono24->write(sample);
+ }
+ }
+ }
+
};
#endif // INCLUDE_UDPSRC_H
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp
index 2ec35bc8d..d2f40764a 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp
@@ -262,7 +262,7 @@ void UDPSrcGUI::setSampleFormatIndex(const UDPSrcSettings::SampleFormat& sampleF
{
switch(sampleFormat)
{
- case UDPSrcSettings::FormatS16LE:
+ case UDPSrcSettings::FormatIQ:
ui->sampleFormat->setCurrentIndex(0);
break;
case UDPSrcSettings::FormatNFM:
@@ -303,7 +303,7 @@ void UDPSrcGUI::setSampleFormat(int index)
switch(index)
{
case 0:
- m_settings.m_sampleFormat = UDPSrcSettings::FormatS16LE;
+ m_settings.m_sampleFormat = UDPSrcSettings::FormatIQ;
ui->fmDeviation->setEnabled(false);
break;
case 1:
@@ -343,7 +343,7 @@ void UDPSrcGUI::setSampleFormat(int index)
ui->fmDeviation->setEnabled(false);
break;
default:
- m_settings.m_sampleFormat = UDPSrcSettings::FormatS16LE;
+ m_settings.m_sampleFormat = UDPSrcSettings::FormatIQ;
ui->fmDeviation->setEnabled(false);
break;
}
@@ -395,6 +395,18 @@ void UDPSrcGUI::on_sampleFormat_currentIndexChanged(int index)
ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
}
+void UDPSrcGUI::on_sampleSize_currentIndexChanged(int index)
+{
+ if ((index < 0) || (index >= UDPSrcSettings::SizeNone)) {
+ return;
+ }
+
+ m_settings.m_sampleSize = (UDPSrcSettings::SampleSize) index;
+
+ ui->applyBtn->setEnabled(true);
+ ui->applyBtn->setStyleSheet("QPushButton { background-color : green; }");
+}
+
void UDPSrcGUI::on_sampleRate_textEdited(const QString& arg1 __attribute__((unused)))
{
bool ok;
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.h b/plugins/channelrx/udpsrc/udpsrcgui.h
index 3827c676d..abeac01d6 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.h
+++ b/plugins/channelrx/udpsrc/udpsrcgui.h
@@ -95,6 +95,7 @@ private:
private slots:
void on_deltaFrequency_changed(qint64 value);
void on_sampleFormat_currentIndexChanged(int index);
+ void on_sampleSize_currentIndexChanged(int index);
void on_sampleRate_textEdited(const QString& arg1);
void on_rfBandwidth_textEdited(const QString& arg1);
void on_fmDeviation_textEdited(const QString& arg1);
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.ui b/plugins/channelrx/udpsrc/udpsrcgui.ui
index 9ab8bc856..8b50c2c30 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.ui
+++ b/plugins/channelrx/udpsrc/udpsrcgui.ui
@@ -364,7 +364,7 @@
-
-
-
+
30
@@ -386,52 +386,69 @@
-
- S16LE I/Q
+ I/Q
-
- S16LE NFM
+ NFM
-
- S16LE NFM Mono
+ NFM Mono
-
- S16LE LSB
+ LSB
-
- S16LE USB
+ USB
-
- S16LE LSB Mono
+ LSB Mono
-
- S16LE USB Mono
+ USB Mono
-
- S16LE AM Mono
+ AM Mono
-
- S16LE AM !DC Mono
+ AM !DC Mono
-
- S16LE AM BPF Mono
+ AM BPF Mono
+
+
+
+
+ -
+
+
+ Samples size
+
+
-
+
+ 16 bits
+
+
+ -
+
+ 24 bits
diff --git a/plugins/channelrx/udpsrc/udpsrcplugin.cpp b/plugins/channelrx/udpsrc/udpsrcplugin.cpp
index b226c4bb1..b6d65e2fc 100644
--- a/plugins/channelrx/udpsrc/udpsrcplugin.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcplugin.cpp
@@ -25,7 +25,7 @@
const PluginDescriptor UDPSrcPlugin::m_pluginDescriptor = {
QString("UDP Channel Source"),
- QString("3.10.1"),
+ QString("3.11.1"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
diff --git a/plugins/channelrx/udpsrc/udpsrcsettings.cpp b/plugins/channelrx/udpsrc/udpsrcsettings.cpp
index 371c9e935..eb28df536 100644
--- a/plugins/channelrx/udpsrc/udpsrcsettings.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcsettings.cpp
@@ -31,7 +31,8 @@ UDPSrcSettings::UDPSrcSettings() :
void UDPSrcSettings::resetToDefaults()
{
m_outputSampleRate = 48000;
- m_sampleFormat = FormatS16LE;
+ m_sampleFormat = FormatIQ;
+ m_sampleSize = Size16bits;
m_inputFrequencyOffset = 0;
m_rfBandwidth = 12500;
m_fmDeviation = 2500;
@@ -77,6 +78,7 @@ QByteArray UDPSrcSettings::serialize() const
s.writeS32(17, m_squelchGate);
s.writeBool(18, m_agc);
s.writeString(19, m_title);
+ s.writeS32(20, (int) m_sampleFormat);
return s.final();
@@ -106,12 +108,12 @@ bool UDPSrcSettings::deserialize(const QByteArray& data)
d.readS32(2, &s32tmp, 0);
m_inputFrequencyOffset = s32tmp;
- d.readS32(3, &s32tmp, FormatS16LE);
+ d.readS32(3, &s32tmp, FormatIQ);
if ((s32tmp >= 0) && (s32tmp < (int) FormatNone)) {
m_sampleFormat = (SampleFormat) s32tmp;
} else {
- m_sampleFormat = FormatS16LE;
+ m_sampleFormat = FormatIQ;
}
d.readReal(4, &m_outputSampleRate, 48000.0);
@@ -134,6 +136,14 @@ bool UDPSrcSettings::deserialize(const QByteArray& data)
d.readBool(18, &m_agc, false);
d.readString(19, &m_title, "UDP Sample Source");
+ d.readS32(20, &s32tmp, Size16bits);
+
+ if ((s32tmp >= 0) && (s32tmp < (int) SizeNone)) {
+ m_sampleSize = (SampleSize) s32tmp;
+ } else {
+ m_sampleSize = Size16bits;
+ }
+
return true;
}
else
diff --git a/plugins/channelrx/udpsrc/udpsrcsettings.h b/plugins/channelrx/udpsrc/udpsrcsettings.h
index 2bd3aa2af..45ee20a14 100644
--- a/plugins/channelrx/udpsrc/udpsrcsettings.h
+++ b/plugins/channelrx/udpsrc/udpsrcsettings.h
@@ -26,7 +26,7 @@ struct Serializable;
struct UDPSrcSettings
{
enum SampleFormat {
- FormatS16LE,
+ FormatIQ,
FormatNFM,
FormatNFMMono,
FormatLSB,
@@ -39,8 +39,15 @@ struct UDPSrcSettings
FormatNone
};
+ enum SampleSize {
+ Size16bits,
+ Size24bits,
+ SizeNone
+ };
+
float m_outputSampleRate;
SampleFormat m_sampleFormat;
+ SampleSize m_sampleSize;
int64_t m_inputFrequencyOffset;
float m_rfBandwidth;
int m_fmDeviation;