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;