diff --git a/CMakeLists.txt b/CMakeLists.txt
index b153e0148..8e6359a87 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,6 +28,7 @@ option(V4L-MSI "Use Linux Kernel MSI2500 Source." OFF)
option(BUILD_TYPE "Build type (RELEASE, RELEASEWITHDBGINFO, DEBUG" RELEASE)
option(DEBUG_OUTPUT "Print debug messages" OFF)
option(HOST_RPI "Compiling on RPi" OFF)
+option(RX_SAMPLE_24BIT "Internal 24 bit Rx DSP" OFF)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
@@ -186,6 +187,9 @@ elseif (${ARCHITECTURE} MATCHES "aarch64")
endif()
# Compiler flags.
+if (RX_SAMPLE_24BIT)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSDR_RX_SAMPLE_24BIT")
+endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fmax-errors=10 -ffast-math -ftree-vectorize ${EXTRA_FLAGS}")
##############################################################################
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/app/main.cpp b/app/main.cpp
index d221ecae4..f1f4cc56d 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -24,6 +24,7 @@
#include "loggerwithfile.h"
#include "mainwindow.h"
+#include "dsp/dsptypes.h"
static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *logger)
{
@@ -34,7 +35,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
*/
QCoreApplication::setOrganizationName("f4exb");
QCoreApplication::setApplicationName("SDRangel");
- QCoreApplication::setApplicationVersion("3.11.0");
+ QCoreApplication::setApplicationVersion("3.11.1");
#if 1
qApp->setStyle(QStyleFactory::create("fusion"));
@@ -95,19 +96,25 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
parser.parse(*qApp);
#if QT_VERSION >= 0x050400
- qInfo("%s %s Qt %s %db %s %s",
+ qInfo("%s %s Qt %s %db %s %s DSP Rx:%db Tx:%db PID %lld",
qPrintable(qApp->applicationName()),
qPrintable(qApp->applicationVersion()),
qPrintable(QString(QT_VERSION_STR)),
QT_POINTER_SIZE*8,
qPrintable(QSysInfo::currentCpuArchitecture()),
- qPrintable(QSysInfo::prettyProductName()));
+ qPrintable(QSysInfo::prettyProductName()),
+ SDR_RX_SAMP_SZ,
+ SDR_TX_SAMP_SZ,
+ qApp->applicationPid());
#else
- qInfo("%s %s Qt %s %db",
+ qInfo("%s %s Qt %s %db DSP Rx:%db Tx:%db PID: %lld",
qPrintable(qApp->applicationName()),
qPrintable((qApp->applicationVersion()),
qPrintable(QString(QT_VERSION_STR)),
- QT_POINTER_SIZE*8);
+ QT_POINTER_SIZE*8,
+ SDR_RX_SAMP_SZ,
+ SDR_TX_SAMP_SZ,
+ applicationPid);
#endif
MainWindow w(logger, parser);
diff --git a/appsrv/main.cpp b/appsrv/main.cpp
index 8183ab273..3cf3a05a0 100644
--- a/appsrv/main.cpp
+++ b/appsrv/main.cpp
@@ -25,6 +25,7 @@
#include "loggerwithfile.h"
#include "maincore.h"
+#include "dsp/dsptypes.h"
void handler(int sig) {
fprintf(stderr, "quit the application by signal(%d).\n", sig);
@@ -55,7 +56,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
QCoreApplication::setOrganizationName("f4exb");
QCoreApplication::setApplicationName("SDRangelSrv");
- QCoreApplication::setApplicationVersion("3.11.0");
+ QCoreApplication::setApplicationVersion("3.11.1");
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
@@ -65,19 +66,25 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
parser.parse(a);
#if QT_VERSION >= 0x050400
- qInfo("%s %s Qt %s %db %s %s",
- qPrintable(qApp->applicationName()),
- qPrintable(qApp->applicationVersion()),
+ qInfo("%s %s Qt %s %db %s %s DSP Rx:%db Tx:%db PID %lld",
+ qPrintable(QCoreApplication::applicationName()),
+ qPrintable(QCoreApplication::applicationVersion()),
qPrintable(QString(QT_VERSION_STR)),
QT_POINTER_SIZE*8,
qPrintable(QSysInfo::currentCpuArchitecture()),
- qPrintable(QSysInfo::prettyProductName()));
+ qPrintable(QSysInfo::prettyProductName()),
+ SDR_RX_SAMP_SZ,
+ SDR_TX_SAMP_SZ,
+ QCoreApplication::applicationPid());
#else
- qInfo("%s %s Qt %s %db",
- qPrintable(qApp->applicationName()),
- qPrintable((qApp->applicationVersion()),
+ qInfo("%s %s Qt %s %db DSP Rx:%db Tx:%db PID %lld",
+ qPrintable(QCoreApplication::applicationName()),
+ qPrintable((QCoreApplication::>applicationVersion()),
qPrintable(QString(QT_VERSION_STR)),
- QT_POINTER_SIZE*8);
+ QT_POINTER_SIZE*8,
+ SDR_RX_SAMP_SZ,
+ SDR_TX_SAMP_SZ,
+ QCoreApplication::applicationPid());
#endif
MainCore m(logger, parser, &a);
diff --git a/debian/changelog b/debian/changelog
index f35a0ad8f..8282b4cfc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+sdrangel (3.11.1-1) unstable; urgency=medium
+
+ * Replaced hardcoded bit scaling literals by defines. 24 bit sample option.
+
+ -- Edouard Griffiths, F4EXB Sun, 28 Jan 2018 12:14:18 +0100
+
sdrangel (3.11.0-1) unstable; urgency=medium
* AirspyHF: support
diff --git a/devices/plutosdr/deviceplutosdrbox.cpp b/devices/plutosdr/deviceplutosdrbox.cpp
index f792f28d2..e5690c17e 100644
--- a/devices/plutosdr/deviceplutosdrbox.cpp
+++ b/devices/plutosdr/deviceplutosdrbox.cpp
@@ -22,6 +22,7 @@
#include
#include
+#include "dsp/dsptypes.h"
#include "dsp/wfir.h"
#include "deviceplutosdr.h"
#include "deviceplutosdrbox.h"
@@ -638,7 +639,7 @@ void DevicePlutoSDRBox::formatFIRCoefficients(std::ostringstream& ostr, uint32_t
WFIR::BasicFIR(fcoeffs, nbTaps, WFIR::LPF, normalizedBW, 0.0, normalizedBW < 0.2 ? WFIR::wtHAMMING : WFIR::wtBLACKMAN_HARRIS, 0.0);
for (unsigned int i = 0; i < nbTaps; i++) {
- ostr << (int16_t) (fcoeffs[i] * 32768.0) << ", " << (int16_t) (fcoeffs[i] * 32768.0) << std::endl;
+ ostr << (int16_t) (fcoeffs[i] * 32768.0f) << ", " << (int16_t) (fcoeffs[i] * 32768.0f) << std::endl;
}
delete[] fcoeffs;
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/libairspyhf/CMakeLists.txt b/libairspyhf/CMakeLists.txt
index 645d76fae..f38afdcbc 100644
--- a/libairspyhf/CMakeLists.txt
+++ b/libairspyhf/CMakeLists.txt
@@ -5,12 +5,14 @@ find_package(LibUSB)
set(airspyhf_SOURCES
${LIBAIRSPYHFSRC}/libairspyhf/src/airspyhf.c
${LIBAIRSPYHFSRC}/libairspyhf/src/iqbalancer.c
+ ${LIBAIRSPYHFSRC}/libairspyhf/src/iqconverter_int16.c
)
set(airspyhf_HEADERS
${LIBAIRSPYHFSRC}/libairspyhf/src/airspyhf.h
${LIBAIRSPYHFSRC}/libairspyhf/src/airspyhf_commands.h
${LIBAIRSPYHFSRC}/libairspyhf/src/iqbalancer.h
+ ${LIBAIRSPYHFSRC}/libairspyhf/src/iqconverter_int16.h
)
include_directories(
diff --git a/plugins/channelrx/chanalyzer/chanalyzer.cpp b/plugins/channelrx/chanalyzer/chanalyzer.cpp
index b26308f38..c8f80498f 100644
--- a/plugins/channelrx/chanalyzer/chanalyzer.cpp
+++ b/plugins/channelrx/chanalyzer/chanalyzer.cpp
@@ -92,7 +92,6 @@ void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const Samp
for(SampleVector::const_iterator it = begin; it < end; ++it)
{
- //Complex c(it->real() / 32768.0f, it->imag() / 32768.0f);
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
@@ -115,16 +114,16 @@ void ChannelAnalyzer::feed(const SampleVector::const_iterator& begin, const Samp
if (!(m_undersampleCount++ & decim_mask))
{
m_sum /= decim;
- m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30);
+ Real re = m_sum.real() / SDR_RX_SCALED;
+ Real im = m_sum.imag() / SDR_RX_SCALED;
+ m_magsq = re*re + im*im;
if (m_ssb & !m_usb)
{ // invert spectrum for LSB
- //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0));
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
}
else
{
- //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0));
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
}
diff --git a/plugins/channelrx/chanalyzer/chanalyzergui.cpp b/plugins/channelrx/chanalyzer/chanalyzergui.cpp
index d68e7b01e..cb3d7ef23 100644
--- a/plugins/channelrx/chanalyzer/chanalyzergui.cpp
+++ b/plugins/channelrx/chanalyzer/chanalyzergui.cpp
@@ -338,8 +338,8 @@ ChannelAnalyzerGUI::ChannelAnalyzerGUI(PluginAPI* pluginAPI, DeviceUISet *device
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
- m_scopeVis = new ScopeVis(ui->glScope);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
+ m_scopeVis = new ScopeVis(SDR_RX_SCALEF, ui->glScope);
m_spectrumScopeComboVis = new SpectrumScopeComboVis(m_spectrumVis, m_scopeVis);
m_channelAnalyzer = (ChannelAnalyzer*) rxChannel; //new ChannelAnalyzer(m_deviceUISet->m_deviceSourceAPI);
m_channelAnalyzer->setSampleSink(m_spectrumScopeComboVis);
diff --git a/plugins/channelrx/chanalyzerng/chanalyzerng.h b/plugins/channelrx/chanalyzerng/chanalyzerng.h
index c80c02ca7..aea652558 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzerng.h
+++ b/plugins/channelrx/chanalyzerng/chanalyzerng.h
@@ -229,16 +229,16 @@ private:
if (!(m_undersampleCount++ & (decim - 1))) // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
{
m_sum /= decim;
- m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30);
+ Real re = m_sum.real() / SDR_RX_SCALED;
+ Real im = m_sum.imag() / SDR_RX_SCALED;
+ m_magsq = re*re + im*im;
if (m_running.m_ssb & !m_usb)
{ // invert spectrum for LSB
- //m_sampleBuffer.push_back(Sample(m_sum.imag() * 32768.0, m_sum.real() * 32768.0));
m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real()));
}
else
{
- //m_sampleBuffer.push_back(Sample(m_sum.real() * 32768.0, m_sum.imag() * 32768.0));
m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag()));
}
diff --git a/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp b/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp
index 6bc2a3561..3441cb265 100644
--- a/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp
+++ b/plugins/channelrx/chanalyzerng/chanalyzernggui.cpp
@@ -395,7 +395,7 @@ ChannelAnalyzerNGGUI::ChannelAnalyzerNGGUI(PluginAPI* pluginAPI, DeviceUISet *de
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_scopeVis = new ScopeVisNG(ui->glScope);
m_spectrumScopeComboVis = new SpectrumScopeNGComboVis(m_spectrumVis, m_scopeVis);
m_channelAnalyzer = (ChannelAnalyzerNG*) rxChannel; //new ChannelAnalyzerNG(m_deviceUISet->m_deviceSourceAPI);
@@ -464,8 +464,6 @@ bool ChannelAnalyzerNGGUI::setNewFinalRate(int spanLog2)
}
m_spanLog2 = spanLog2;
- //m_rate = 48000 / (1<getInputSampleRate() / (1<real() / 32768.0, it->imag() / 32768.0);
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
diff --git a/plugins/channelrx/demodam/amdemod.h b/plugins/channelrx/demodam/amdemod.h
index b6cc056e3..ccbab6fb5 100644
--- a/plugins/channelrx/demodam/amdemod.h
+++ b/plugins/channelrx/demodam/amdemod.h
@@ -161,8 +161,9 @@ private:
void processOneSample(Complex &ci)
{
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ Real re = ci.real() / SDR_RX_SCALED;
+ Real im = ci.imag() / SDR_RX_SCALED;
+ Real magsq = re*re + im*im;
m_movingAverage.feed(magsq);
m_magsq = m_movingAverage.average();
m_magsqSum += magsq;
@@ -209,7 +210,7 @@ private:
Real attack = (m_squelchCount - 0.05f * m_settings.m_audioSampleRate) / (0.05f * m_settings.m_audioSampleRate);
sample = demod * attack * 2048 * m_settings.m_volume;
- if (m_settings.m_copyAudioToUDP) m_udpBufferAudio->write(demod * attack * 32768);
+ if (m_settings.m_copyAudioToUDP) m_udpBufferAudio->write(demod * attack * SDR_RX_SCALEF);
m_squelchOpen = true;
}
diff --git a/plugins/channelrx/demodatv/atvdemod.cpp b/plugins/channelrx/demodatv/atvdemod.cpp
index 1635e6c7d..db14c76aa 100644
--- a/plugins/channelrx/demodatv/atvdemod.cpp
+++ b/plugins/channelrx/demodatv/atvdemod.cpp
@@ -338,8 +338,7 @@ void ATVDemod::demod(Complex& c)
magSq = fltI*fltI + fltQ*fltQ;
m_objMagSqAverage.feed(magSq);
fltNorm = sqrt(magSq);
- fltVal = fltNorm / (1<<15);
- //fltVal = magSq / (1<<30);
+ fltVal = fltNorm / SDR_RX_SCALEF;
//********** Mini and Maxi Amplitude tracking **********
@@ -414,7 +413,7 @@ void ATVDemod::demod(Complex& c)
fltVal = (fltVal < -1.0f) ? -1.0f : (fltVal > 1.0f) ? 1.0f : fltVal;
if ((m_running.m_intVideoTabIndex == 1) && (m_scopeSink != 0)) { // feed scope buffer only if scope is present and visible
- m_scopeSampleBuffer.push_back(Sample(fltVal*32767.0f, 0.0f));
+ m_scopeSampleBuffer.push_back(Sample(fltVal*SDR_RX_SCALEF, 0.0f));
}
m_fltAmpLineAverage += fltVal;
diff --git a/plugins/channelrx/demodatv/atvdemodgui.cpp b/plugins/channelrx/demodatv/atvdemodgui.cpp
index 365ccb329..530f9e95f 100644
--- a/plugins/channelrx/demodatv/atvdemodgui.cpp
+++ b/plugins/channelrx/demodatv/atvdemodgui.cpp
@@ -474,7 +474,7 @@ void ATVDemodGUI::tick()
if (m_atvDemod)
{
m_objMagSqAverage.feed(m_atvDemod->getMagSq());
- double magSqDB = CalcDb::dbPower(m_objMagSqAverage.average() / (1<<30));
+ double magSqDB = CalcDb::dbPower(m_objMagSqAverage.average() / (SDR_RX_SCALED*SDR_RX_SCALED));
ui->channePowerText->setText(tr("%1 dB").arg(magSqDB, 0, 'f', 1));
if (m_atvDemod->getBFOLocked()) {
diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp
index 5dc2f6075..8e432c33a 100644
--- a/plugins/channelrx/demodbfm/bfmdemod.cpp
+++ b/plugins/channelrx/demodbfm/bfmdemod.cpp
@@ -125,7 +125,7 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
for (SampleVector::const_iterator it = begin; it != end; ++it)
{
- Complex c(it->real() / 32768.0f, it->imag() / 32768.0f);
+ Complex c(it->real() / SDR_RX_SCALEF, it->imag() / SDR_RX_SCALEF);
c *= m_nco.nextIQ();
rf_out = m_rfFilter->runFilt(c, &rf); // filter RF before demod
@@ -163,7 +163,7 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
if (!m_settings.m_showPilot)
{
- m_sampleBuffer.push_back(Sample(demod * (1<<15), 0.0));
+ m_sampleBuffer.push_back(Sample(demod * SDR_RX_SCALEF, 0.0));
}
if (m_settings.m_rdsActive)
@@ -197,7 +197,7 @@ void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
if (m_settings.m_showPilot)
{
- m_sampleBuffer.push_back(Sample(m_pilotPLLSamples[1] * (1<<15), 0.0)); // debug 38 kHz pilot
+ m_sampleBuffer.push_back(Sample(m_pilotPLLSamples[1] * SDR_RX_SCALEF, 0.0)); // debug 38 kHz pilot
}
if (m_settings.m_lsbStereo)
diff --git a/plugins/channelrx/demodbfm/bfmdemodgui.cpp b/plugins/channelrx/demodbfm/bfmdemodgui.cpp
index 0a298aa90..fdce5b17d 100644
--- a/plugins/channelrx/demodbfm/bfmdemodgui.cpp
+++ b/plugins/channelrx/demodbfm/bfmdemodgui.cpp
@@ -344,7 +344,7 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_bfmDemod = (BFMDemod*) rxChannel; //new BFMDemod(m_deviceUISet->m_deviceSourceAPI);
m_bfmDemod->setMessageQueueToGUI(getInputMessageQueue());
m_bfmDemod->setSampleSink(m_spectrumVis);
diff --git a/plugins/channelrx/demoddsd/dsddemod.cpp b/plugins/channelrx/demoddsd/dsddemod.cpp
index a02c8c637..6f188d37c 100644
--- a/plugins/channelrx/demoddsd/dsddemod.cpp
+++ b/plugins/channelrx/demoddsd/dsddemod.cpp
@@ -65,8 +65,9 @@ DSDDemod::DSDDemod(DeviceSourceAPI *deviceAPI) :
m_audioBuffer.resize(1<<14);
m_audioBufferFill = 0;
- m_sampleBuffer = new qint16[1<<17]; // 128 kS
+ m_sampleBuffer = new FixReal[1<<17]; // 128 kS
m_sampleBufferIndex = 0;
+ m_scaleFromShort = SDR_RX_SAMP_SZ < sizeof(short)*8 ? 1 : 1<<(SDR_RX_SAMP_SZ - sizeof(short)*8);
m_movingAverage.resize(16, 0);
m_magsq = 0.0f;
@@ -126,9 +127,12 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
{
- qint16 sample, delayedSample;
+ FixReal sample, delayedSample;
+ qint16 sampleDSD;
- Real magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())) / (1<<30);
+ Real re = ci.real() / SDR_RX_SCALED;
+ Real im = ci.imag() / SDR_RX_SCALED;
+ Real magsq = re*re + im*im;
m_movingAverage.feed(magsq);
m_magsqSum += magsq;
@@ -140,7 +144,7 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
m_magsqCount++;
- Real demod = 32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_demodGain;
+ Real demod = m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_demodGain; // [-1.0:1.0]
m_sampleCount++;
// AF processing
@@ -168,17 +172,19 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
if (m_squelchOpen)
{
- sample = demod;
+ sampleDSD = demod * 32768.0f; // DSD decoder takes int16 samples
+ sample = demod * SDR_RX_SCALEF; // scale to sample size
}
else
{
+ sampleDSD = 0;
sample = 0;
}
- m_dsdDecoder.pushSample(sample);
+ m_dsdDecoder.pushSample(sampleDSD);
if (m_settings.m_enableCosineFiltering) { // show actual input to FSK demod
- sample = m_dsdDecoder.getFilteredSample();
+ sample = m_dsdDecoder.getFilteredSample() * m_scaleFromShort;
}
if (m_sampleBufferIndex < (1<<17)) {
@@ -197,7 +203,7 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
if (m_settings.m_syncOrConstellation)
{
- Sample s(sample, m_dsdDecoder.getSymbolSyncSample());
+ Sample s(sample, m_dsdDecoder.getSymbolSyncSample() * m_scaleFromShort);
m_scopeSampleBuffer.push_back(s);
}
else
diff --git a/plugins/channelrx/demoddsd/dsddemod.h b/plugins/channelrx/demoddsd/dsddemod.h
index 80ec2d758..299703474 100644
--- a/plugins/channelrx/demoddsd/dsddemod.h
+++ b/plugins/channelrx/demoddsd/dsddemod.h
@@ -186,8 +186,9 @@ private:
SampleVector m_scopeSampleBuffer;
AudioVector m_audioBuffer;
uint m_audioBufferFill;
- qint16 *m_sampleBuffer; //!< samples ring buffer
+ FixReal *m_sampleBuffer; //!< samples ring buffer
int m_sampleBufferIndex;
+ int m_scaleFromShort;
AudioFifo m_audioFifo1;
AudioFifo m_audioFifo2;
diff --git a/plugins/channelrx/demoddsd/dsddemodgui.cpp b/plugins/channelrx/demoddsd/dsddemodgui.cpp
index bff4ce0a8..863a7ff6b 100644
--- a/plugins/channelrx/demoddsd/dsddemodgui.cpp
+++ b/plugins/channelrx/demoddsd/dsddemodgui.cpp
@@ -269,7 +269,7 @@ DSDDemodGUI::DSDDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
- m_scopeVis = new ScopeVis(ui->glScope);
+ m_scopeVis = new ScopeVis(SDR_RX_SCALEF, ui->glScope);
m_dsdDemod = (DSDDemod*) rxChannel; //new DSDDemod(m_deviceUISet->m_deviceSourceAPI);
m_dsdDemod->setScopeSink(m_scopeVis);
m_dsdDemod->setMessageQueueToGUI(getInputMessageQueue());
diff --git a/plugins/channelrx/demoddsd/dsddemodplugin.cpp b/plugins/channelrx/demoddsd/dsddemodplugin.cpp
index 9d0ce86fd..fac69c490 100644
--- a/plugins/channelrx/demoddsd/dsddemodplugin.cpp
+++ b/plugins/channelrx/demoddsd/dsddemodplugin.cpp
@@ -25,7 +25,7 @@
const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = {
QString("DSD Demodulator"),
- 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/demodlora/lorademod.cpp b/plugins/channelrx/demodlora/lorademod.cpp
index fe2b96d0f..b0b397279 100644
--- a/plugins/channelrx/demodlora/lorademod.cpp
+++ b/plugins/channelrx/demodlora/lorademod.cpp
@@ -261,7 +261,7 @@ void LoRaDemod::feed(const SampleVector::const_iterator& begin, const SampleVect
for(SampleVector::const_iterator it = begin; it < end; ++it)
{
- Complex c(it->real() / 32768.0f, it->imag() / 32768.0f);
+ Complex c(it->real() / SDR_RX_SCALEF, it->imag() / SDR_RX_SCALEF);
c *= m_nco.nextIQ();
if(m_interpolator.decimate(&m_sampleDistanceRemain, c, &ci))
diff --git a/plugins/channelrx/demodlora/lorademodgui.cpp b/plugins/channelrx/demodlora/lorademodgui.cpp
index 82dfa464d..f70abc72c 100644
--- a/plugins/channelrx/demodlora/lorademodgui.cpp
+++ b/plugins/channelrx/demodlora/lorademodgui.cpp
@@ -117,7 +117,7 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_LoRaDemod = (LoRaDemod*) rxChannel; //new LoRaDemod(m_deviceUISet->m_deviceSourceAPI);
m_LoRaDemod->setSpectrumSink(m_spectrumVis);
diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp
index bf2c1965d..db7243800 100644
--- a/plugins/channelrx/demodnfm/nfmdemod.cpp
+++ b/plugins/channelrx/demodnfm/nfmdemod.cpp
@@ -153,7 +153,7 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
Real demod = m_phaseDiscri.phaseDiscriminatorDelta(ci, magsqRaw, deviation);
- Real magsq = magsqRaw / (1<<30);
+ Real magsq = magsqRaw / (SDR_RX_SCALED*SDR_RX_SCALED);
m_movingAverage.feed(magsq);
m_magsqSum += magsq;
diff --git a/plugins/channelrx/demodssb/ssbdemod.cpp b/plugins/channelrx/demodssb/ssbdemod.cpp
index 581608fb3..743985adb 100644
--- a/plugins/channelrx/demodssb/ssbdemod.cpp
+++ b/plugins/channelrx/demodssb/ssbdemod.cpp
@@ -77,7 +77,7 @@ SSBDemod::SSBDemod(DeviceSourceAPI *deviceAPI) :
m_magsqPeak = 0.0f;
m_magsqCount = 0;
- m_agc.setClampMax(32768.0*32768.0);
+ m_agc.setClampMax(SDR_RX_SCALED*SDR_RX_SCALED);
m_agc.setClamping(m_agcClamping);
SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, ssbFftLen);
@@ -154,7 +154,6 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
for(SampleVector::const_iterator it = begin; it < end; ++it)
{
- //Complex c(it->real() / 32768.0, it->imag() / 32768.0);
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
@@ -187,7 +186,7 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
{
Real avgr = m_sum.real() / decim;
Real avgi = m_sum.imag() / decim;
- m_magsq = (avgr * avgr + avgi * avgi) / (1<<30);
+ m_magsq = (avgr * avgr + avgi * avgi) / (SDR_RX_SCALED*SDR_RX_SCALED);
m_magsqSum += m_magsq;
@@ -428,7 +427,7 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force)
{
int agcNbSamples = 48 * (1<glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_ssbDemod = (SSBDemod*) rxChannel; //new SSBDemod(m_deviceUISet->m_deviceSourceAPI);
m_ssbDemod->setMessageQueueToGUI(getInputMessageQueue());
m_ssbDemod->setSampleSink(m_spectrumVis);
diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp
index 5a8cd282d..20db5d5fe 100644
--- a/plugins/channelrx/demodwfm/wfmdemod.cpp
+++ b/plugins/channelrx/demodwfm/wfmdemod.cpp
@@ -104,7 +104,6 @@ void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
for (SampleVector::const_iterator it = begin; it != end; ++it)
{
- //Complex c(it->real() / 32768.0f, it->imag() / 32768.0f);
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
@@ -113,7 +112,7 @@ void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
for (int i = 0 ; i < rf_out; i++)
{
demod = m_phaseDiscri.phaseDiscriminatorDelta(rf[i], msq, fmDev);
- Real magsq = msq / (1<<30);
+ Real magsq = msq / (SDR_RX_SCALED*SDR_RX_SCALED);
m_movingAverage.feed(magsq);
m_magsqSum += magsq;
diff --git a/plugins/channelrx/tcpsrc/tcpsrc.cpp b/plugins/channelrx/tcpsrc/tcpsrc.cpp
index a92a043cc..9ab708d2e 100644
--- a/plugins/channelrx/tcpsrc/tcpsrc.cpp
+++ b/plugins/channelrx/tcpsrc/tcpsrc.cpp
@@ -97,17 +97,15 @@ void TCPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
m_settingsMutex.lock();
// Rtl-Sdr uses full 16-bit scale; FCDPP does not
- //int rescale = 32768 * (1 << m_boost);
int rescale = (1 << m_volume);
for(SampleVector::const_iterator it = begin; it < end; ++it) {
- //Complex c(it->real() / 32768.0f, it->imag() / 32768.0f);
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
if(m_interpolator.decimate(&m_sampleDistanceRemain, c, &ci))
{
- m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())*rescale*rescale) / (1<<30);
+ m_magsq = ((ci.real()*ci.real() + ci.imag()*ci.imag())*rescale*rescale) / (SDR_RX_SCALED*SDR_RX_SCALED);
m_sampleBuffer.push_back(Sample(ci.real() * rescale, ci.imag() * rescale));
m_sampleDistanceRemain += m_inputSampleRate / m_outputSampleRate;
}
@@ -145,7 +143,7 @@ void TCPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
if((m_sampleFormat == TCPSrcSettings::FormatNFM) && (m_ssbSockets.count() > 0)) {
for(SampleVector::const_iterator it = m_sampleBuffer.begin(); it != m_sampleBuffer.end(); ++it) {
- Complex cj(it->real() / 32768.0f, it->imag() / 32768.0f);
+ Complex cj(it->real() / SDR_RX_SCALEF, it->imag() / SDR_RX_SCALEF);
// An FFT filter here is overkill, but was already set up for SSB
int n_out = TCPFilter->runFilt(cj, &sideband);
if (n_out) {
diff --git a/plugins/channelrx/tcpsrc/tcpsrcgui.cpp b/plugins/channelrx/tcpsrc/tcpsrcgui.cpp
index 0f2b5fad9..5e0cc50eb 100644
--- a/plugins/channelrx/tcpsrc/tcpsrcgui.cpp
+++ b/plugins/channelrx/tcpsrc/tcpsrcgui.cpp
@@ -132,7 +132,7 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
setAttribute(Qt::WA_DeleteOnClose, true);
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_tcpSrc = (TCPSrc*) rxChannel; //new TCPSrc(m_deviceUISet->m_deviceSourceAPI);
m_tcpSrc->setSpectrum(m_spectrumVis);
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 c0aa7be87..f89f60da3 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];
@@ -92,7 +94,7 @@ UDPSrc::UDPSrc(DeviceSourceAPI *deviceAPI) :
qWarning("UDPSrc::UDPSrc: cannot bind audio port");
}
- m_agc.setClampMax(32768.0*32768.0);
+ m_agc.setClampMax(SDR_RX_SCALED*SDR_RX_SCALED);
m_agc.setClamping(true);
//DSPEngine::instance()->addAudioSink(&m_audioFifo);
@@ -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();
@@ -158,7 +162,7 @@ void UDPSrc::feed(const SampleVector::const_iterator& begin, const SampleVector:
inMagSq = ci.real()*ci.real() + ci.imag()*ci.imag();
}
- m_inMovingAverage.feed(inMagSq / (1<<30));
+ m_inMovingAverage.feed(inMagSq / (SDR_RX_SCALED*SDR_RX_SCALED));
m_inMagsq = m_inMovingAverage.average();
Sample ss(ci.real(), ci.imag());
@@ -179,8 +183,8 @@ 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));
- m_outMovingAverage.feed((l*l + r*r) / (1<<30));
+ udpWrite(l, r);
+ m_outMovingAverage.feed((l*l + r*r) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
}
}
@@ -195,22 +199,22 @@ 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));
- m_outMovingAverage.feed((l*l + r*r) / (1<<30));
+ 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 ? 32768.0 * m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain : 0;
- m_udpBuffer->write(Sample(demod, demod));
- m_outMovingAverage.feed((demod * demod) / (1<<30));
+ Real discri = m_squelchOpen ? m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain : 0;
+ udpWriteNorm(discri, discri);
+ m_outMovingAverage.feed(discri*discri);
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatNFMMono)
{
- FixReal demod = m_squelchOpen ? (FixReal) (32768.0f * m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain) : 0;
- m_udpBufferMono->write(demod);
- m_outMovingAverage.feed((demod * demod) / 1073741824.0);
+ Real discri = m_squelchOpen ? m_phaseDiscri.phaseDiscriminator(ci) * m_settings.m_gain : 0;
+ udpWriteNormMono(discri);
+ m_outMovingAverage.feed(discri*discri);
}
else if (m_settings.m_sampleFormat == UDPSrcSettings::FormatLSBMono) // Monaural LSB
{
@@ -222,8 +226,8 @@ 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);
- m_outMovingAverage.feed((l * l) / (1<<30));
+ udpWriteMono(l);
+ m_outMovingAverage.feed((l * l) / (SDR_RX_SCALED*SDR_RX_SCALED));
}
}
}
@@ -237,16 +241,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);
- m_outMovingAverage.feed((l * l) / (1<<30));
+ 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) / 1073741824.0);
+ 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 +259,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) / 1073741824.0);
+ 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 +277,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) / 1073741824.0);
+ 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 +292,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);
- m_outMovingAverage.feed((inMagSq*m_settings.m_gain*m_settings.m_gain) / (1<<30));
+ 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 +489,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 +574,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..9e9864d4e 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,64 @@ 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);
+ }
+ }
+ }
+
+ void udpWriteNorm(Real real, Real imag)
+ {
+ if (m_settings.m_sampleSize == UDPSrcSettings::Size16bits) {
+ m_udpBuffer16->write(Sample16(real*32768.0, imag*32768.0));
+ } else if (m_settings.m_sampleSize == UDPSrcSettings::Size24bits) {
+ m_udpBuffer24->write(Sample24(real*8388608.0, imag*8388608.0));
+ }
+ }
+
+ void udpWriteNormMono(Real sample)
+ {
+ if (m_settings.m_sampleSize == UDPSrcSettings::Size16bits) {
+ m_udpBufferMono16->write(sample*32768.0);
+ } else if (m_settings.m_sampleSize == UDPSrcSettings::Size24bits) {
+ m_udpBufferMono24->write(sample*8388608.0);
+ }
+ }
+
};
#endif // INCLUDE_UDPSRC_H
diff --git a/plugins/channelrx/udpsrc/udpsrcgui.cpp b/plugins/channelrx/udpsrc/udpsrcgui.cpp
index 48918ad19..d2f40764a 100644
--- a/plugins/channelrx/udpsrc/udpsrcgui.cpp
+++ b/plugins/channelrx/udpsrc/udpsrcgui.cpp
@@ -147,7 +147,7 @@ UDPSrcGUI::UDPSrcGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
setAttribute(Qt::WA_DeleteOnClose, true);
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_RX_SCALEF, ui->glSpectrum);
m_udpSrc = (UDPSrc*) rxChannel; //new UDPSrc(m_deviceUISet->m_deviceSourceAPI);
m_udpSrc->setSpectrum(m_spectrumVis);
@@ -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;
diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp
index d8fe9016f..479eb39c2 100644
--- a/plugins/channeltx/modam/ammod.cpp
+++ b/plugins/channeltx/modam/ammod.cpp
@@ -129,8 +129,8 @@ void AMMod::pull(Sample& sample)
m_settingsMutex.unlock();
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
+ magsq /= (SDR_TX_SCALED*SDR_TX_SCALED);
m_movingAverage.feed(magsq);
m_magsq = m_movingAverage.average();
diff --git a/plugins/channeltx/modatv/atvmod.cpp b/plugins/channeltx/modatv/atvmod.cpp
index f28b6ae93..35dc83fdf 100644
--- a/plugins/channeltx/modatv/atvmod.cpp
+++ b/plugins/channeltx/modatv/atvmod.cpp
@@ -163,8 +163,8 @@ void ATVMod::pullFinalize(Complex& ci, Sample& sample)
m_settingsMutex.unlock();
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
+ magsq /= (SDR_TX_SCALED*SDR_TX_SCALED);
m_movingAverage.feed(magsq);
sample.m_real = (FixReal) ci.real();
diff --git a/plugins/channeltx/modatv/atvmodsettings.cpp b/plugins/channeltx/modatv/atvmodsettings.cpp
index 1b5014d3c..dc32d0371 100644
--- a/plugins/channeltx/modatv/atvmodsettings.cpp
+++ b/plugins/channeltx/modatv/atvmodsettings.cpp
@@ -43,7 +43,7 @@ void ATVModSettings::resetToDefaults()
m_cameraPlay = false;
m_channelMute = false;
m_invertedVideo = false;
- m_rfScalingFactor = 29204.0f; // -1dB
+ m_rfScalingFactor = 0.891235351562f * SDR_TX_SCALEF; // -1dB
m_fmExcursion = 0.5f; // half bandwidth
m_forceDecimator = false;
m_overlayText = "ATV";
diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp
index dad97319c..2d49ef740 100644
--- a/plugins/channeltx/modnfm/nfmmod.cpp
+++ b/plugins/channeltx/modnfm/nfmmod.cpp
@@ -135,8 +135,8 @@ void NFMMod::pull(Sample& sample)
m_settingsMutex.unlock();
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
+ magsq /= (SDR_TX_SCALED*SDR_TX_SCALED);
m_movingAverage.feed(magsq);
m_magsq = m_movingAverage.average();
@@ -175,8 +175,8 @@ void NFMMod::modulateSample()
m_modPhasor += (m_settings.m_fmDeviation / (float) m_settings.m_audioSampleRate) * m_bandpass.filter(t) * (M_PI / 378.0f);
}
- m_modSample.real(cos(m_modPhasor) * 29204.0f); // -1 dB
- m_modSample.imag(sin(m_modPhasor) * 29204.0f);
+ m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
+ m_modSample.imag(sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF);
}
void NFMMod::pullAF(Real& sample)
diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp
index ad90f716e..662abc634 100644
--- a/plugins/channeltx/modssb/ssbmod.cpp
+++ b/plugins/channeltx/modssb/ssbmod.cpp
@@ -160,12 +160,12 @@ void SSBMod::pull(Sample& sample)
m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
- ci *= 29204.0f; //scaling at -1 dB to account for possible filter overshoot
+ ci *= 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
m_settingsMutex.unlock();
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
+ magsq /= (SDR_TX_SCALED*SDR_TX_SCALED);
m_movingAverage.feed(magsq);
m_magsq = m_movingAverage.average();
@@ -298,13 +298,13 @@ void SSBMod::pullAF(Complex& sample)
{
if (m_settings.m_audioFlipChannels)
{
- ci.real((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_settings.m_volumeFactor);
- ci.imag((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_settings.m_volumeFactor);
+ ci.real((m_audioBuffer[m_audioBufferFill].r / SDR_TX_SCALEF) * m_settings.m_volumeFactor);
+ ci.imag((m_audioBuffer[m_audioBufferFill].l / SDR_TX_SCALEF) * m_settings.m_volumeFactor);
}
else
{
- ci.real((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_settings.m_volumeFactor);
- ci.imag((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_settings.m_volumeFactor);
+ ci.real((m_audioBuffer[m_audioBufferFill].l / SDR_TX_SCALEF) * m_settings.m_volumeFactor);
+ ci.imag((m_audioBuffer[m_audioBufferFill].r / SDR_TX_SCALEF) * m_settings.m_volumeFactor);
}
}
else
@@ -419,18 +419,8 @@ void SSBMod::pullAF(Complex& sample)
if (!(m_undersampleCount++ & decim_mask))
{
- Real avgr = (m_sum.real() / decim) * 29204.0f; //scaling at -1 dB to account for possible filter overshoot
- Real avgi = (m_sum.imag() / decim) * 29204.0f;
-// m_magsqSpectrum = (avgr * avgr + avgi * avgi) / (1<<30);
-//
-// m_magsqSum += m_magsqSpectrum;
-//
-// if (m_magsqSpectrum > m_magsqPeak)
-// {
-// m_magsqPeak = m_magsqSpectrum;
-// }
-//
-// m_magsqCount++;
+ Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
+ Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
if (!m_settings.m_dsb & !m_settings.m_usb)
{ // invert spectrum for LSB
@@ -453,18 +443,8 @@ void SSBMod::pullAF(Complex& sample)
if (!(m_undersampleCount++ & decim_mask))
{
- Real avgr = (m_sum.real() / decim) * 29204.0f; //scaling at -1 dB to account for possible filter overshoot
- Real avgi = (m_sum.imag() / decim) * 29204.0f;
-// m_magsqSpectrum = (avgr * avgr + avgi * avgi) / (1<<30);
-//
-// m_magsqSum += m_magsqSpectrum;
-//
-// if (m_magsqSpectrum > m_magsqPeak)
-// {
-// m_magsqPeak = m_magsqSpectrum;
-// }
-//
-// m_magsqCount++;
+ Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
+ Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
if (!m_settings.m_dsb & !m_settings.m_usb)
{ // invert spectrum for LSB
diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp
index 2ba54f94c..3f093e40e 100644
--- a/plugins/channeltx/modssb/ssbmodgui.cpp
+++ b/plugins/channeltx/modssb/ssbmodgui.cpp
@@ -364,7 +364,7 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_TX_SCALEF, ui->glSpectrum);
m_ssbMod = (SSBMod*) channelTx; //new SSBMod(m_deviceUISet->m_deviceSinkAPI);
m_ssbMod->setSpectrumSampleSink(m_spectrumVis);
m_ssbMod->setMessageQueueToGUI(getInputMessageQueue());
diff --git a/plugins/channeltx/modwfm/wfmmod.cpp b/plugins/channeltx/modwfm/wfmmod.cpp
index 3801a255f..87bf31fc6 100644
--- a/plugins/channeltx/modwfm/wfmmod.cpp
+++ b/plugins/channeltx/modwfm/wfmmod.cpp
@@ -139,8 +139,8 @@ void WFMMod::pull(Sample& sample)
}
m_modPhasor += (m_settings.m_fmDeviation / (float) m_outputSampleRate) * ri.real() * M_PI * 2.0f;
- ci.real(cos(m_modPhasor) * 29204.0f); // -1 dB
- ci.imag(sin(m_modPhasor) * 29204.0f);
+ ci.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
+ ci.imag(sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF);
// RF filtering
rf_out = m_rfFilter->runFilt(ci, &rf);
@@ -157,8 +157,8 @@ void WFMMod::pull(Sample& sample)
m_settingsMutex.unlock();
- Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
+ magsq /= (SDR_TX_SCALED*SDR_TX_SCALED);
m_movingAverage.feed(magsq);
m_magsq = m_movingAverage.average();
diff --git a/plugins/channeltx/udpsink/udpsink.cpp b/plugins/channeltx/udpsink/udpsink.cpp
index 889376930..3915fabf4 100644
--- a/plugins/channeltx/udpsink/udpsink.cpp
+++ b/plugins/channeltx/udpsink/udpsink.cpp
@@ -134,7 +134,7 @@ void UDPSink::pull(Sample& sample)
m_settingsMutex.unlock();
double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
- magsq /= (1<<30);
+ magsq /= (SDR_TX_SCALED*SDR_TX_SCALED);
m_movingAverage.feed(magsq);
m_magsq = m_movingAverage.average();
@@ -151,7 +151,7 @@ void UDPSink::modulateSample()
m_udpHandler.readSample(s);
uint64_t magsq = s.m_real * s.m_real + s.m_imag * s.m_imag;
- m_inMovingAverage.feed(magsq/1073741824.0);
+ m_inMovingAverage.feed(magsq/(SDR_TX_SCALED*SDR_TX_SCALED));
m_inMagsq = m_inMovingAverage.average();
calculateSquelch(m_inMagsq);
@@ -180,9 +180,9 @@ void UDPSink::modulateSample()
if (m_squelchOpen)
{
- m_modPhasor += (m_settings.m_fmDeviation / m_settings.m_inputSampleRate) * (t / 32768.0f) * M_PI * 2.0f;
- m_modSample.real(cos(m_modPhasor) * 10362.2f * m_settings.m_gainOut);
- m_modSample.imag(sin(m_modPhasor) * 10362.2f * m_settings.m_gainOut);
+ m_modPhasor += (m_settings.m_fmDeviation / m_settings.m_inputSampleRate) * (t / SDR_TX_SCALEF) * M_PI * 2.0f;
+ m_modSample.real(cos(m_modPhasor) * 0.3162292f * SDR_TX_SCALEF * m_settings.m_gainOut);
+ m_modSample.imag(sin(m_modPhasor) * 0.3162292f * SDR_TX_SCALEF * m_settings.m_gainOut);
calculateLevel(m_modSample);
}
else
@@ -195,14 +195,14 @@ void UDPSink::modulateSample()
{
FixReal t;
readMonoSample(t);
- m_inMovingAverage.feed((t*t)/1073741824.0);
+ m_inMovingAverage.feed((t*t)/(SDR_TX_SCALED*SDR_TX_SCALED));
m_inMagsq = m_inMovingAverage.average();
calculateSquelch(m_inMagsq);
if (m_squelchOpen)
{
- m_modSample.real(((t / 32768.0f)*m_settings.m_amModFactor*m_settings.m_gainOut + 1.0f) * 16384.0f); // modulate and scale zero frequency carrier
+ m_modSample.real(((t / SDR_TX_SCALEF)*m_settings.m_amModFactor*m_settings.m_gainOut + 1.0f) * (SDR_TX_SCALEF/2)); // modulate and scale zero frequency carrier
m_modSample.imag(0.0f);
calculateLevel(m_modSample);
}
@@ -220,14 +220,14 @@ void UDPSink::modulateSample()
int n_out = 0;
readMonoSample(t);
- m_inMovingAverage.feed((t*t)/1073741824.0);
+ m_inMovingAverage.feed((t*t)/(SDR_TX_SCALED*SDR_TX_SCALED));
m_inMagsq = m_inMovingAverage.average();
calculateSquelch(m_inMagsq);
if (m_squelchOpen)
{
- ci.real((t / 32768.0f) * m_settings.m_gainOut);
+ ci.real((t / SDR_TX_SCALEF) * m_settings.m_gainOut);
ci.imag(0.0f);
n_out = m_SSBFilter->runSSB(ci, &filtered, (m_settings.m_sampleFormat == UDPSinkSettings::FormatUSB));
@@ -239,8 +239,8 @@ void UDPSink::modulateSample()
}
c = m_SSBFilterBuffer[m_SSBFilterBufferIndex];
- m_modSample.real(m_SSBFilterBuffer[m_SSBFilterBufferIndex].real() * 32768.0f);
- m_modSample.imag(m_SSBFilterBuffer[m_SSBFilterBufferIndex].imag() * 32768.0f);
+ m_modSample.real(m_SSBFilterBuffer[m_SSBFilterBufferIndex].real() * SDR_TX_SCALEF);
+ m_modSample.imag(m_SSBFilterBuffer[m_SSBFilterBufferIndex].imag() * SDR_TX_SCALEF);
m_SSBFilterBufferIndex++;
calculateLevel(m_modSample);
@@ -305,8 +305,8 @@ void UDPSink::calculateLevel(Complex sample)
}
else
{
- qreal rmsLevel = m_levelSum > 0.0 ? sqrt((m_levelSum/(1<<30)) / m_levelNbSamples) : 0.0;
- emit levelChanged(rmsLevel, m_peakLevel / 32768.0, m_levelNbSamples);
+ qreal rmsLevel = m_levelSum > 0.0 ? sqrt((m_levelSum/(SDR_TX_SCALED*SDR_TX_SCALED)) / m_levelNbSamples) : 0.0;
+ emit levelChanged(rmsLevel, m_peakLevel / SDR_TX_SCALEF, m_levelNbSamples);
m_peakLevel = 0.0f;
m_levelSum = 0.0f;
m_levelCalcCount = 0;
diff --git a/plugins/channeltx/udpsink/udpsinkgui.cpp b/plugins/channeltx/udpsink/udpsinkgui.cpp
index d408c0b9b..36ef4dbbf 100644
--- a/plugins/channeltx/udpsink/udpsinkgui.cpp
+++ b/plugins/channeltx/udpsink/udpsinkgui.cpp
@@ -119,7 +119,7 @@ UDPSinkGUI::UDPSinkGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
setAttribute(Qt::WA_DeleteOnClose, true);
- m_spectrumVis = new SpectrumVis(ui->glSpectrum);
+ m_spectrumVis = new SpectrumVis(SDR_TX_SCALEF, ui->glSpectrum);
m_udpSink = (UDPSink*) channelTx; //new UDPSink(m_deviceUISet->m_deviceSinkAPI);
m_udpSink->setSpectrumSink(m_spectrumVis);
m_udpSink->setMessageQueueToGUI(getInputMessageQueue());
diff --git a/plugins/samplesink/bladerfoutput/bladerfoutputthread.h b/plugins/samplesink/bladerfoutput/bladerfoutputthread.h
index 7a973161b..4a93140e0 100644
--- a/plugins/samplesink/bladerfoutput/bladerfoutputthread.h
+++ b/plugins/samplesink/bladerfoutput/bladerfoutputthread.h
@@ -51,7 +51,7 @@ private:
unsigned int m_log2Interp;
int m_fcPos;
- Interpolators m_interpolators;
+ Interpolators m_interpolators;
void run();
void callback(qint16* buf, qint32 len);
diff --git a/plugins/samplesink/filesink/filesinkthread.h b/plugins/samplesink/filesink/filesinkthread.h
index e408d0b39..3c7b820f7 100644
--- a/plugins/samplesink/filesink/filesinkthread.h
+++ b/plugins/samplesink/filesink/filesinkthread.h
@@ -70,7 +70,7 @@ private:
QElapsedTimer m_elapsedTimer;
bool m_throttleToggle;
- Interpolators m_interpolators;
+ Interpolators m_interpolators;
int16_t *m_buf;
void run();
diff --git a/plugins/samplesink/hackrfoutput/hackrfoutputthread.h b/plugins/samplesink/hackrfoutput/hackrfoutputthread.h
index 5e51cff2d..f44139a0e 100644
--- a/plugins/samplesink/hackrfoutput/hackrfoutputthread.h
+++ b/plugins/samplesink/hackrfoutput/hackrfoutputthread.h
@@ -49,7 +49,7 @@ private:
unsigned int m_log2Interp;
- Interpolators m_interpolators;
+ Interpolators m_interpolators;
void run();
void callback(qint8* buf, qint32 len);
diff --git a/plugins/samplesink/limesdroutput/limesdroutputthread.h b/plugins/samplesink/limesdroutput/limesdroutputthread.h
index 7acd125cc..e543d510c 100644
--- a/plugins/samplesink/limesdroutput/limesdroutputthread.h
+++ b/plugins/samplesink/limesdroutput/limesdroutputthread.h
@@ -56,7 +56,7 @@ private:
unsigned int m_log2Interp; // soft decimation
int m_fcPos;
- Interpolators m_interpolators;
+ Interpolators m_interpolators;
void run();
void callback(qint16* buf, qint32 len);
diff --git a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp
index 8ad6cdaa2..d6493a1ea 100644
--- a/plugins/samplesink/plutosdroutput/plutosdroutput.cpp
+++ b/plugins/samplesink/plutosdroutput/plutosdroutput.cpp
@@ -221,7 +221,6 @@ bool PlutoSDROutput::handleMessage(const Message& message)
bool PlutoSDROutput::openDevice()
{
- //m_sampleSourceFifo.resize(m_settings.m_devSampleRate/(1<<(m_settings.m_log2Interp <= 4 ? m_settings.m_log2Interp : 4)));
m_sampleSourceFifo.resize(32*PLUTOSDR_BLOCKSIZE_SAMPLES);
// look for Rx buddy and get reference to common parameters
diff --git a/plugins/samplesink/plutosdroutput/plutosdroutputthread.h b/plugins/samplesink/plutosdroutput/plutosdroutputthread.h
index 7669fceca..782c6e389 100644
--- a/plugins/samplesink/plutosdroutput/plutosdroutputthread.h
+++ b/plugins/samplesink/plutosdroutput/plutosdroutputthread.h
@@ -54,7 +54,7 @@ private:
unsigned int m_log2Interp; // soft interpolation
- Interpolators m_interpolators;
+ Interpolators m_interpolators;
void run();
void convert(qint16* buf, qint32 len);
diff --git a/plugins/samplesource/airspy/airspythread.h b/plugins/samplesource/airspy/airspythread.h
index 52fa601e3..b21c894d3 100644
--- a/plugins/samplesource/airspy/airspythread.h
+++ b/plugins/samplesource/airspy/airspythread.h
@@ -55,7 +55,11 @@ private:
int m_fcPos;
static AirspyThread *m_this;
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void callback(const qint16* buf, qint32 len);
diff --git a/plugins/samplesource/airspyhf/airspyhfthread.h b/plugins/samplesource/airspyhf/airspyhfthread.h
index 0056f5f87..615bf8275 100644
--- a/plugins/samplesource/airspyhf/airspyhfthread.h
+++ b/plugins/samplesource/airspyhf/airspyhfthread.h
@@ -53,7 +53,11 @@ private:
unsigned int m_log2Decim;
static AirspyHFThread *m_this;
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void callback(const qint16* buf, qint32 len);
diff --git a/plugins/samplesource/bladerfinput/bladerfinputthread.h b/plugins/samplesource/bladerfinput/bladerfinputthread.h
index 4cebd38b9..8230c5c90 100644
--- a/plugins/samplesource/bladerfinput/bladerfinputthread.h
+++ b/plugins/samplesource/bladerfinput/bladerfinputthread.h
@@ -51,7 +51,11 @@ private:
unsigned int m_log2Decim;
int m_fcPos;
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void callback(const qint16* buf, qint32 len);
diff --git a/plugins/samplesource/filesource/filesourcegui.cpp b/plugins/samplesource/filesource/filesourcegui.cpp
index 1de88aa7f..d679ae889 100644
--- a/plugins/samplesource/filesource/filesourcegui.cpp
+++ b/plugins/samplesource/filesource/filesourcegui.cpp
@@ -175,6 +175,7 @@ bool FileSourceGui::handleMessage(const Message& message)
else if (FileSourceInput::MsgReportFileSourceStreamData::match(message))
{
m_sampleRate = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getSampleRate();
+ m_sampleSize = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getSampleSize();
m_centerFrequency = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getCenterFrequency();
m_startingTimeStamp = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getStartingTimeStamp();
m_recordLength = ((FileSourceInput::MsgReportFileSourceStreamData&)message).getRecordLength();
@@ -312,6 +313,7 @@ void FileSourceGui::updateWithStreamData()
{
ui->centerFrequency->setValue(m_centerFrequency/1000);
ui->sampleRateText->setText(tr("%1k").arg((float)m_sampleRate / 1000));
+ ui->sampleSizeText->setText(tr("%1b").arg(m_sampleSize));
ui->play->setEnabled(m_acquisition);
QTime recordLength(0, 0, 0, 0);
recordLength = recordLength.addSecs(m_recordLength);
diff --git a/plugins/samplesource/filesource/filesourcegui.h b/plugins/samplesource/filesource/filesourcegui.h
index e5a040346..a580d528f 100644
--- a/plugins/samplesource/filesource/filesourcegui.h
+++ b/plugins/samplesource/filesource/filesourcegui.h
@@ -63,6 +63,7 @@ private:
bool m_acquisition;
QString m_fileName;
int m_sampleRate;
+ quint32 m_sampleSize;
quint64 m_centerFrequency;
quint32 m_recordLength;
std::time_t m_startingTimeStamp;
diff --git a/plugins/samplesource/filesource/filesourcegui.ui b/plugins/samplesource/filesource/filesourcegui.ui
index f33b1e2a7..20ec4bc82 100644
--- a/plugins/samplesource/filesource/filesourcegui.ui
+++ b/plugins/samplesource/filesource/filesourcegui.ui
@@ -6,7 +6,7 @@
0
0
- 246
+ 300
190
@@ -231,16 +231,56 @@
-
+
+
+ 40
+ 0
+
+
8
- Record sample rate
+ Record sample rate (kS/s)
- 0k
+ 00000k
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+
+ 22
+ 0
+
+
+
+
+ 8
+
+
+
+ Record sample size (bits)
+
+
+ 00b
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
diff --git a/plugins/samplesource/filesource/filesourceinput.cpp b/plugins/samplesource/filesource/filesourceinput.cpp
index 8a6b79b72..354a0ad65 100644
--- a/plugins/samplesource/filesource/filesourceinput.cpp
+++ b/plugins/samplesource/filesource/filesourceinput.cpp
@@ -48,6 +48,7 @@ FileSourceInput::FileSourceInput(DeviceSourceAPI *deviceAPI) :
m_deviceDescription(),
m_fileName("..."),
m_sampleRate(0),
+ m_sampleSize(0),
m_centerFrequency(0),
m_recordLength(0),
m_startingTimeStamp(0),
@@ -85,6 +86,7 @@ void FileSourceInput::openFileStream()
m_sampleRate = header.sampleRate;
m_centerFrequency = header.centerFrequency;
m_startingTimeStamp = header.startTimeStamp;
+ m_sampleSize = header.sampleSize;
if (fileSize > sizeof(FileRecord::Header)) {
m_recordLength = (fileSize - sizeof(FileRecord::Header)) / (4 * m_sampleRate);
@@ -97,6 +99,7 @@ void FileSourceInput::openFileStream()
<< " length: " << m_recordLength << " seconds";
MsgReportFileSourceStreamData *report = MsgReportFileSourceStreamData::create(m_sampleRate,
+ m_sampleSize,
m_centerFrequency,
m_startingTimeStamp,
m_recordLength); // file stream data
@@ -136,7 +139,7 @@ bool FileSourceInput::start()
m_ifstream.seekg(sizeof(FileRecord::Header), std::ios::beg);
}
- if(!m_sampleFifo.setSize(m_sampleRate * 4)) {
+ if(!m_sampleFifo.setSize(m_sampleRate * sizeof(Sample))) {
qCritical("Could not allocate SampleFifo");
return false;
}
@@ -149,7 +152,7 @@ bool FileSourceInput::start()
return false;
}
- m_fileSourceThread->setSamplerate(m_sampleRate);
+ m_fileSourceThread->setSampleRateAndSize(m_sampleRate, m_sampleSize);
m_fileSourceThread->connectTimer(m_masterTimer);
m_fileSourceThread->startWork();
m_deviceDescription = "FileSource";
diff --git a/plugins/samplesource/filesource/filesourceinput.h b/plugins/samplesource/filesource/filesourceinput.h
index e3e157468..92df61eab 100644
--- a/plugins/samplesource/filesource/filesourceinput.h
+++ b/plugins/samplesource/filesource/filesourceinput.h
@@ -173,30 +173,35 @@ public:
public:
int getSampleRate() const { return m_sampleRate; }
+ quint32 getSampleSize() const { return m_sampleSize; }
quint64 getCenterFrequency() const { return m_centerFrequency; }
std::time_t getStartingTimeStamp() const { return m_startingTimeStamp; }
quint32 getRecordLength() const { return m_recordLength; }
static MsgReportFileSourceStreamData* create(int sampleRate,
+ quint32 sampleSize,
quint64 centerFrequency,
std::time_t startingTimeStamp,
quint32 recordLength)
{
- return new MsgReportFileSourceStreamData(sampleRate, centerFrequency, startingTimeStamp, recordLength);
+ return new MsgReportFileSourceStreamData(sampleRate, sampleSize, centerFrequency, startingTimeStamp, recordLength);
}
protected:
int m_sampleRate;
+ quint32 m_sampleSize;
quint64 m_centerFrequency;
std::time_t m_startingTimeStamp;
quint32 m_recordLength;
MsgReportFileSourceStreamData(int sampleRate,
+ quint32 sampleSize,
quint64 centerFrequency,
std::time_t startingTimeStamp,
quint32 recordLength) :
Message(),
m_sampleRate(sampleRate),
+ m_sampleSize(sampleSize),
m_centerFrequency(centerFrequency),
m_startingTimeStamp(startingTimeStamp),
m_recordLength(recordLength)
@@ -265,6 +270,7 @@ public:
QString m_deviceDescription;
QString m_fileName;
int m_sampleRate;
+ quint32 m_sampleSize;
quint64 m_centerFrequency;
quint32 m_recordLength; //!< record length in seconds computed from file size
std::time_t m_startingTimeStamp;
diff --git a/plugins/samplesource/filesource/filesourceplugin.cpp b/plugins/samplesource/filesource/filesourceplugin.cpp
index 4705c4de4..f4a962afd 100644
--- a/plugins/samplesource/filesource/filesourceplugin.cpp
+++ b/plugins/samplesource/filesource/filesourceplugin.cpp
@@ -29,7 +29,7 @@
const PluginDescriptor FileSourcePlugin::m_pluginDescriptor = {
QString("File source input"),
- QString("3.10.1"),
+ QString("3.11.1"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
diff --git a/plugins/samplesource/filesource/filesourcethread.cpp b/plugins/samplesource/filesource/filesourcethread.cpp
index 0df5d73c5..d69099bbf 100644
--- a/plugins/samplesource/filesource/filesourcethread.cpp
+++ b/plugins/samplesource/filesource/filesourcethread.cpp
@@ -27,12 +27,15 @@ FileSourceThread::FileSourceThread(std::ifstream *samplesStream, SampleSinkFifo*
QThread(parent),
m_running(false),
m_ifstream(samplesStream),
- m_buf(0),
+ m_fileBuf(0),
+ m_convertBuf(0),
m_bufsize(0),
m_chunksize(0),
m_sampleFifo(sampleFifo),
m_samplesCount(0),
m_samplerate(0),
+ m_samplesize(0),
+ m_samplebytes(0),
m_throttlems(FILESOURCE_THROTTLE_MS),
m_throttleToggle(false)
{
@@ -45,8 +48,12 @@ FileSourceThread::~FileSourceThread()
stopWork();
}
- if (m_buf != 0) {
- free(m_buf);
+ if (m_fileBuf != 0) {
+ free(m_fileBuf);
+ }
+
+ if (m_convertBuf != 0) {
+ free(m_convertBuf);
}
}
@@ -77,49 +84,67 @@ void FileSourceThread::stopWork()
wait();
}
-void FileSourceThread::setSamplerate(int samplerate)
+void FileSourceThread::setSampleRateAndSize(int samplerate, quint32 samplesize)
{
- qDebug() << "FileSourceThread::setSamplerate:"
- << " new:" << samplerate
- << " old:" << m_samplerate;
+ qDebug() << "FileSourceThread::setSampleRateAndSize:"
+ << " new rate:" << samplerate
+ << " new size:" << samplesize
+ << " old rate:" << m_samplerate
+ << " old size:" << m_samplesize;
- if (samplerate != m_samplerate)
+ if ((samplerate != m_samplerate) || (samplesize != m_samplesize))
{
if (m_running) {
stopWork();
}
m_samplerate = samplerate;
- // TODO: implement FF and slow motion here. 4 corresponds to live. 2 is half speed, 8 is doulbe speed
- m_chunksize = (m_samplerate * 4 * m_throttlems) / 1000;
+ m_samplesize = samplesize;
+ m_samplebytes = m_samplesize > 16 ? sizeof(int32_t) : sizeof(int16_t);
+ // TODO: implement FF and slow motion here. 2 corresponds to live. 1 is half speed, 4 is double speed
+ m_chunksize = (m_samplerate * 2 * m_samplebytes * m_throttlems) / 1000;
- setBuffer(m_chunksize);
+ setBuffers(m_chunksize);
}
//m_samplerate = samplerate;
}
-void FileSourceThread::setBuffer(std::size_t chunksize)
+void FileSourceThread::setBuffers(std::size_t chunksize)
{
if (chunksize > m_bufsize)
{
m_bufsize = chunksize;
+ int nbSamples = m_bufsize/(2 * m_samplebytes);
- if (m_buf == 0)
+ if (m_fileBuf == 0)
{
- qDebug() << "FileSourceThread::setBuffer: Allocate buffer";
- m_buf = (quint8*) malloc(m_bufsize);
+ qDebug() << "FileSourceThread::setBuffers: Allocate file buffer";
+ m_fileBuf = (quint8*) malloc(m_bufsize);
}
else
{
- qDebug() << "FileSourceThread::setBuffer: Re-allocate buffer";
- quint8 *buf = m_buf;
- m_buf = (quint8*) realloc((void*) m_buf, m_bufsize);
- if (!m_buf) free(buf);
+ qDebug() << "FileSourceThread::setBuffers: Re-allocate file buffer";
+ quint8 *buf = m_fileBuf;
+ m_fileBuf = (quint8*) realloc((void*) m_fileBuf, m_bufsize);
+ if (!m_fileBuf) free(buf);
}
- qDebug() << "FileSourceThread::setBuffer: size: " << m_bufsize
- << " #samples: " << (m_bufsize/4);
+ if (m_convertBuf == 0)
+ {
+ qDebug() << "FileSourceThread::setBuffers: Allocate conversion buffer";
+ m_convertBuf = (quint8*) malloc(nbSamples*sizeof(Sample));
+ }
+ else
+ {
+ qDebug() << "FileSourceThread::setBuffers: Re-allocate conversion buffer";
+ quint8 *buf = m_convertBuf;
+ m_convertBuf = (quint8*) realloc((void*) m_convertBuf, nbSamples*sizeof(Sample));
+ if (!m_convertBuf) free(buf);
+ }
+
+ qDebug() << "FileSourceThread::setBuffers: size: " << m_bufsize
+ << " #samples: " << nbSamples;
}
}
@@ -151,17 +176,18 @@ void FileSourceThread::tick()
if (throttlems != m_throttlems)
{
m_throttlems = throttlems;
- m_chunksize = 4 * ((m_samplerate * (m_throttlems+(m_throttleToggle ? 1 : 0))) / 1000);
+ m_chunksize = 2 * m_samplebytes * ((m_samplerate * (m_throttlems+(m_throttleToggle ? 1 : 0))) / 1000);
m_throttleToggle = !m_throttleToggle;
- setBuffer(m_chunksize);
+ setBuffers(m_chunksize);
}
// read samples directly feeding the SampleFifo (no callback)
- m_ifstream->read(reinterpret_cast(m_buf), m_chunksize);
+ m_ifstream->read(reinterpret_cast(m_fileBuf), m_chunksize);
if (m_ifstream->eof())
{
- m_sampleFifo->write(m_buf, m_ifstream->gcount());
+ writeToSampleFifo(m_fileBuf, (qint32) m_ifstream->gcount());
+ //m_sampleFifo->write(m_buf, m_ifstream->gcount());
// TODO: handle loop playback situation
m_ifstream->clear();
m_ifstream->seekg(sizeof(FileRecord::Header), std::ios::beg);
@@ -171,8 +197,55 @@ void FileSourceThread::tick()
}
else
{
- m_sampleFifo->write(m_buf, m_chunksize);
- m_samplesCount += m_chunksize / 4;
+ writeToSampleFifo(m_fileBuf, (qint32) m_chunksize);
+ //m_sampleFifo->write(m_buf, m_chunksize);
+ m_samplesCount += m_chunksize / (2 * m_samplebytes);
}
}
}
+
+void FileSourceThread::writeToSampleFifo(const quint8* buf, qint32 nbBytes)
+{
+ if (m_samplesize == 16)
+ {
+ if (SDR_RX_SAMP_SZ == 16)
+ {
+ m_sampleFifo->write(buf, nbBytes);
+ }
+ else if (SDR_RX_SAMP_SZ == 24)
+ {
+ FixReal *convertBuf = (FixReal *) m_convertBuf;
+ const int16_t *fileBuf = (int16_t *) buf;
+ int nbSamples = nbBytes / (2 * m_samplebytes);
+
+ for (int is = 0; is < nbSamples; is++)
+ {
+ convertBuf[2*is] = fileBuf[2*is] << 8;
+ convertBuf[2*is+1] = fileBuf[2*is+1] << 8;
+ }
+
+ m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
+ }
+ }
+ else if (m_samplesize == 24)
+ {
+ if (SDR_RX_SAMP_SZ == 24)
+ {
+ m_sampleFifo->write(buf, nbBytes);
+ }
+ else if (SDR_RX_SAMP_SZ == 16)
+ {
+ FixReal *convertBuf = (FixReal *) m_convertBuf;
+ const int32_t *fileBuf = (int32_t *) buf;
+ int nbSamples = nbBytes / (2 * m_samplebytes);
+
+ for (int is = 0; is < nbSamples; is++)
+ {
+ convertBuf[2*is] = fileBuf[2*is] >> 8;
+ convertBuf[2*is+1] = fileBuf[2*is+1] >> 8;
+ }
+
+ m_sampleFifo->write((quint8*) convertBuf, nbSamples*sizeof(Sample));
+ }
+ }
+}
diff --git a/plugins/samplesource/filesource/filesourcethread.h b/plugins/samplesource/filesource/filesourcethread.h
index ca777a241..ff483b84d 100644
--- a/plugins/samplesource/filesource/filesourcethread.h
+++ b/plugins/samplesource/filesource/filesourcethread.h
@@ -41,8 +41,8 @@ public:
void startWork();
void stopWork();
- void setSamplerate(int samplerate);
- void setBuffer(std::size_t chunksize);
+ void setSampleRateAndSize(int samplerate, quint32 samplesize);
+ void setBuffers(std::size_t chunksize);
bool isRunning() const { return m_running; }
std::size_t getSamplesCount() const { return m_samplesCount; }
void setSamplesCount(int samplesCount) { m_samplesCount = samplesCount; }
@@ -55,20 +55,23 @@ private:
bool m_running;
std::ifstream* m_ifstream;
- quint8 *m_buf;
+ quint8 *m_fileBuf;
+ quint8 *m_convertBuf;
std::size_t m_bufsize;
std::size_t m_chunksize;
SampleSinkFifo* m_sampleFifo;
std::size_t m_samplesCount;
- int m_samplerate;
+ int m_samplerate; //!< File I/Q stream original sample rate
+ quint32 m_samplesize; //!< File effective sample size in bits (I or Q). Ex: 16, 24.
+ quint32 m_samplebytes; //!< Number of bytes used to store a I or Q sample. Ex: 2. 4.
int m_throttlems;
QElapsedTimer m_elapsedTimer;
bool m_throttleToggle;
void run();
//void decimate1(SampleVector::iterator* it, const qint16* buf, qint32 len);
- //void callback(const qint16* buf, qint32 len);
+ void writeToSampleFifo(const quint8* buf, qint32 nbBytes);
private slots:
void tick();
};
diff --git a/plugins/samplesource/hackrfinput/hackrfinputthread.h b/plugins/samplesource/hackrfinput/hackrfinputthread.h
index 5ef0fb32a..32df49077 100644
--- a/plugins/samplesource/hackrfinput/hackrfinputthread.h
+++ b/plugins/samplesource/hackrfinput/hackrfinputthread.h
@@ -54,7 +54,11 @@ private:
unsigned int m_log2Decim;
int m_fcPos;
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void callback(const qint8* buf, qint32 len);
diff --git a/plugins/samplesource/limesdrinput/limesdrinputthread.h b/plugins/samplesource/limesdrinput/limesdrinputthread.h
index dd5fb3772..096083ac8 100644
--- a/plugins/samplesource/limesdrinput/limesdrinputthread.h
+++ b/plugins/samplesource/limesdrinput/limesdrinputthread.h
@@ -55,7 +55,11 @@ private:
unsigned int m_log2Decim; // soft decimation
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void callback(const qint16* buf, qint32 len);
diff --git a/plugins/samplesource/plutosdrinput/plutosdrinputthread.h b/plugins/samplesource/plutosdrinput/plutosdrinputthread.h
index f6373deb2..e79630334 100644
--- a/plugins/samplesource/plutosdrinput/plutosdrinputthread.h
+++ b/plugins/samplesource/plutosdrinput/plutosdrinputthread.h
@@ -59,7 +59,11 @@ private:
int m_fcPos;
float m_phasor;
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void convert(const qint16* buf, qint32 len);
diff --git a/plugins/samplesource/rtlsdr/rtlsdrthread.h b/plugins/samplesource/rtlsdr/rtlsdrthread.h
index 5c4d7ed9f..97f3ed56d 100644
--- a/plugins/samplesource/rtlsdr/rtlsdrthread.h
+++ b/plugins/samplesource/rtlsdr/rtlsdrthread.h
@@ -52,7 +52,11 @@ private:
unsigned int m_log2Decim;
int m_fcPos;
- DecimatorsU m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ DecimatorsU m_decimators;
+#else
+ DecimatorsU m_decimators;
+#endif
void run();
void callback(const quint8* buf, qint32 len);
diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.cpp
index b2d375237..1ab67e08c 100644
--- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.cpp
+++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.cpp
@@ -174,7 +174,7 @@ void SDRdaemonSourceBuffer::checkSlotData(int slotIndex)
if (sampleRate > 0)
{
int64_t ts = m_currentMeta.m_tv_sec * 1000000LL + m_currentMeta.m_tv_usec;
- ts -= (rwDelayBytes * 1000000LL) / (sampleRate * sizeof(Sample));
+ ts -= (rwDelayBytes * 1000000LL) / (sampleRate * sizeof(SDRdaemonSample));
m_tvOut_sec = ts / 1000000LL;
m_tvOut_usec = ts - (m_tvOut_sec * 1000000LL);
}
diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h
index dab6d5aa3..5613ecac0 100644
--- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h
+++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourcebuffer.h
@@ -55,7 +55,7 @@ public:
}
};
- struct Sample
+ struct SDRdaemonSample
{
int16_t i;
int16_t q;
@@ -68,12 +68,12 @@ public:
uint8_t filler;
};
- static const int samplesPerBlock = (SDRDAEMONSOURCE_UDPSIZE - sizeof(Header)) / sizeof(Sample);
+ static const int samplesPerBlock = (SDRDAEMONSOURCE_UDPSIZE - sizeof(Header)) / sizeof(SDRdaemonSample);
static const int framesSize = SDRDAEMONSOURCE_NBDECODERSLOTS * (SDRDAEMONSOURCE_NBORIGINALBLOCKS - 1) * (SDRDAEMONSOURCE_UDPSIZE - sizeof(Header));
struct ProtectedBlock
{
- Sample samples[samplesPerBlock];
+ SDRdaemonSample samples[samplesPerBlock];
};
struct SuperBlock
diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceplugin.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceplugin.cpp
index 7cda55a7f..8f5b33517 100644
--- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceplugin.cpp
+++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceplugin.cpp
@@ -26,7 +26,7 @@
const PluginDescriptor SDRdaemonSourcePlugin::m_pluginDescriptor = {
QString("SDRdaemon source input"),
- QString("3.9.0"),
+ QString("3.11.1"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp
index e9120f1e8..a60062a85 100644
--- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp
+++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.cpp
@@ -51,6 +51,8 @@ SDRdaemonSourceUDPHandler::SDRdaemonSourceUDPHandler(SampleSinkFifo *sampleFifo,
m_throttlems(SDRDAEMONSOURCE_THROTTLE_MS),
m_readLengthSamples(0),
m_readLength(0),
+ m_converterBuffer(0),
+ m_converterBufferNbSamples(0),
m_throttleToggle(false),
m_rateDivider(1000/SDRDAEMONSOURCE_THROTTLE_MS),
m_autoCorrBuffer(true)
@@ -72,6 +74,7 @@ SDRdaemonSourceUDPHandler::~SDRdaemonSourceUDPHandler()
{
stop();
delete[] m_udpBuf;
+ if (m_converterBuffer) { delete[] m_converterBuffer; }
#ifdef USE_INTERNAL_TIMER
if (m_timer) {
delete m_timer;
@@ -263,9 +266,32 @@ void SDRdaemonSourceUDPHandler::tick()
m_readLength = m_readLengthSamples * SDRdaemonSourceBuffer::m_iqSampleSize;
- // read samples directly feeding the SampleFifo (no callback)
- m_sampleFifo->write(reinterpret_cast(m_sdrDaemonBuffer.readData(m_readLength)), m_readLength);
- m_samplesCount += m_readLengthSamples;
+ if (SDR_RX_SAMP_SZ == 16)
+ {
+ // read samples directly feeding the SampleFifo (no callback)
+ m_sampleFifo->write(reinterpret_cast(m_sdrDaemonBuffer.readData(m_readLength)), m_readLength);
+ m_samplesCount += m_readLengthSamples;
+ }
+ else if (SDR_RX_SAMP_SZ == 24)
+ {
+ if (m_readLengthSamples > m_converterBufferNbSamples)
+ {
+ if (m_converterBuffer) { delete[] m_converterBuffer; }
+ m_converterBuffer = new int32_t[m_readLengthSamples*2];
+ }
+
+ uint8_t *buf = m_sdrDaemonBuffer.readData(m_readLength);
+
+ for (unsigned int is = 0; is < m_readLengthSamples; is++)
+ {
+ m_converterBuffer[2*is] = ((int16_t*)buf)[2*is];
+ m_converterBuffer[2*is]<<=8;
+ m_converterBuffer[2*is+1] = ((int16_t*)buf)[2*is+1];
+ m_converterBuffer[2*is+1]<<=8;
+ }
+
+ m_sampleFifo->write(reinterpret_cast(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
+ }
if (m_tickCount < m_rateDivider)
{
diff --git a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h
index 8a96e6978..0f686329a 100644
--- a/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h
+++ b/plugins/samplesource/sdrdaemonsource/sdrdaemonsourceudphandler.h
@@ -77,6 +77,8 @@ private:
int m_throttlems;
uint32_t m_readLengthSamples;
uint32_t m_readLength;
+ int32_t *m_converterBuffer;
+ uint32_t m_converterBufferNbSamples;
bool m_throttleToggle;
uint32_t m_rateDivider;
bool m_autoCorrBuffer;
diff --git a/plugins/samplesource/sdrplay/sdrplaythread.h b/plugins/samplesource/sdrplay/sdrplaythread.h
index 2882f4a44..807db699c 100644
--- a/plugins/samplesource/sdrplay/sdrplaythread.h
+++ b/plugins/samplesource/sdrplay/sdrplaythread.h
@@ -52,7 +52,11 @@ private:
unsigned int m_log2Decim;
int m_fcPos;
- Decimators m_decimators;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators;
+#else
+ Decimators m_decimators;
+#endif
void run();
void callback(const qint16* buf, qint32 len);
diff --git a/plugins/samplesource/testsource/testsourcethread.h b/plugins/samplesource/testsource/testsourcethread.h
index d7f237cb6..d8a8f219c 100644
--- a/plugins/samplesource/testsource/testsourcethread.h
+++ b/plugins/samplesource/testsource/testsourcethread.h
@@ -85,9 +85,15 @@ private:
bool m_throttleToggle;
QMutex m_mutex;
- Decimators m_decimators_8;
- Decimators m_decimators_12;
- Decimators m_decimators_16;
+#ifdef SDR_RX_SAMPLE_24BIT
+ Decimators m_decimators_8;
+ Decimators m_decimators_12;
+ Decimators m_decimators_16;
+#else
+ Decimators m_decimators_8;
+ Decimators m_decimators_12;
+ Decimators m_decimators_16;
+#endif
void run();
void callback(const qint16* buf, qint32 len);
diff --git a/sdrbase/dsp/decimators.h b/sdrbase/dsp/decimators.h
index c4645c2da..9abd7350c 100644
--- a/sdrbase/dsp/decimators.h
+++ b/sdrbase/dsp/decimators.h
@@ -18,11 +18,15 @@
#define INCLUDE_GPL_DSP_DECIMATORS_H_
#include "dsp/dsptypes.h"
+#ifdef SDR_RX_SAMPLE_24BIT
+#include "dsp/inthalfbandfilterdb.h"
+#else
#ifdef USE_SSE4_1
#include "dsp/inthalfbandfiltereo1.h"
#else
#include "dsp/inthalfbandfilterdb.h"
#endif
+#endif
#define DECIMATORS_HB_FILTER_ORDER 64
@@ -44,6 +48,42 @@ struct decimation_shifts
static const uint post64 = 0;
};
+template<>
+struct decimation_shifts<16, 24>
+{
+ static const uint pre1 = 0;
+ static const uint pre2 = 0;
+ static const uint post2 = 9;
+ static const uint pre4 = 0;
+ static const uint post4 = 10;
+ static const uint pre8 = 0;
+ static const uint post8 = 11;
+ static const uint pre16 = 0;
+ static const uint post16 = 12;
+ static const uint pre32 = 0;
+ static const uint post32 = 13;
+ static const uint pre64 = 0;
+ static const uint post64 = 14;
+};
+
+template<>
+struct decimation_shifts<24, 24>
+{
+ static const uint pre1 = 0;
+ static const uint pre2 = 0;
+ static const uint post2 = 1;
+ static const uint pre4 = 0;
+ static const uint post4 = 2;
+ static const uint pre8 = 0;
+ static const uint post8 = 3;
+ static const uint pre16 = 0;
+ static const uint post16 = 4;
+ static const uint pre32 = 0;
+ static const uint post32 = 5;
+ static const uint pre64 = 0;
+ static const uint post64 = 6;
+};
+
template<>
struct decimation_shifts<16, 16>
{
@@ -62,6 +102,24 @@ struct decimation_shifts<16, 16>
static const uint post64 = 6;
};
+template<>
+struct decimation_shifts<24, 16>
+{
+ static const uint pre1 = 8;
+ static const uint pre2 = 7;
+ static const uint post2 = 0;
+ static const uint pre4 = 6;
+ static const uint post4 = 0;
+ static const uint pre8 = 5;
+ static const uint post8 = 0;
+ static const uint pre16 = 4;
+ static const uint post16 = 0;
+ static const uint pre32 = 3;
+ static const uint post32 = 0;
+ static const uint pre64 = 2;
+ static const uint post64 = 0;
+};
+
template<>
struct decimation_shifts<16, 12>
{
@@ -80,6 +138,24 @@ struct decimation_shifts<16, 12>
static const uint post64 = 2;
};
+template<>
+struct decimation_shifts<24, 12>
+{
+ static const uint pre1 = 12;
+ static const uint pre2 = 11;
+ static const uint post2 = 0;
+ static const uint pre4 = 10;
+ static const uint post4 = 0;
+ static const uint pre8 = 9;
+ static const uint post8 = 0;
+ static const uint pre16 = 8;
+ static const uint post16 = 0;
+ static const uint pre32 = 7;
+ static const uint post32 = 0;
+ static const uint pre64 = 6;
+ static const uint post64 = 0;
+};
+
template<>
struct decimation_shifts<16, 8>
{
@@ -98,7 +174,25 @@ struct decimation_shifts<16, 8>
static const uint post64 = 0;
};
-template
+template<>
+struct decimation_shifts<24, 8>
+{
+ static const uint pre1 = 16;
+ static const uint pre2 = 15;
+ static const uint post2 = 0;
+ static const uint pre4 = 14;
+ static const uint post4 = 0;
+ static const uint pre8 = 13;
+ static const uint post8 = 0;
+ static const uint pre16 = 12;
+ static const uint post16 = 0;
+ static const uint pre32 = 11;
+ static const uint post32 = 0;
+ static const uint pre64 = 10;
+ static const uint post64 = 0;
+};
+
+template
class Decimators
{
public:
@@ -146,6 +240,14 @@ public:
void decimate64_cen(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len);
private:
+#ifdef SDR_RX_SAMPLE_24BIT
+ IntHalfbandFilterDB m_decimator2; // 1st stages
+ IntHalfbandFilterDB m_decimator4; // 2nd stages
+ IntHalfbandFilterDB m_decimator8; // 3rd stages
+ IntHalfbandFilterDB m_decimator16; // 4th stages
+ IntHalfbandFilterDB m_decimator32; // 5th stages
+ IntHalfbandFilterDB m_decimator64; // 6th stages
+#else
#ifdef USE_SSE4_1
IntHalfbandFilterEO1 m_decimator2; // 1st stages
IntHalfbandFilterEO1 m_decimator4; // 2nd stages
@@ -154,17 +256,18 @@ private:
IntHalfbandFilterEO1 m_decimator32; // 5th stages
IntHalfbandFilterEO1 m_decimator64; // 6th stages
#else
- IntHalfbandFilterDB m_decimator2; // 1st stages
- IntHalfbandFilterDB m_decimator4; // 2nd stages
- IntHalfbandFilterDB m_decimator8; // 3rd stages
- IntHalfbandFilterDB m_decimator16; // 4th stages
- IntHalfbandFilterDB m_decimator32; // 5th stages
- IntHalfbandFilterDB m_decimator64; // 6th stages
+ IntHalfbandFilterDB m_decimator2; // 1st stages
+ IntHalfbandFilterDB m_decimator4; // 2nd stages
+ IntHalfbandFilterDB m_decimator8; // 3rd stages
+ IntHalfbandFilterDB m_decimator16; // 4th stages
+ IntHalfbandFilterDB m_decimator32; // 5th stages
+ IntHalfbandFilterDB m_decimator64; // 6th stages
+#endif
#endif
};
-template
-void Decimators::decimate1(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate1(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint32 xreal, yimag;
@@ -178,8 +281,8 @@ void Decimators::decimate1(SampleVector::iterator* it, co
}
}
-template
-void Decimators::decimate1(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate1(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
qint32 xreal, yimag;
@@ -193,10 +296,10 @@ void Decimators::decimate1(SampleVector::iterator* it, co
}
}
-template
-void Decimators::decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
@@ -214,10 +317,10 @@ void Decimators::decimate2_u(SampleVector::iterator* it,
}
}
-template
-void Decimators::decimate2_u(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate2_u(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 3; pos += 4)
{
@@ -237,10 +340,10 @@ void Decimators::decimate2_u(SampleVector::iterator* it,
}
}
-template
-void Decimators::decimate2_inf(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate2_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
@@ -258,10 +361,10 @@ void Decimators::decimate2_inf(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate2_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate2_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 3; pos += 4)
{
@@ -281,10 +384,10 @@ void Decimators::decimate2_inf(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate2_sup(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate2_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
@@ -302,10 +405,10 @@ void Decimators::decimate2_sup(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate2_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate2_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 3; pos += 4)
{
@@ -325,10 +428,10 @@ void Decimators::decimate2_sup(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate4_inf(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate4_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
@@ -342,10 +445,10 @@ void Decimators::decimate4_inf(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate4_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate4_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 3; pos += 4)
{
@@ -359,8 +462,8 @@ void Decimators::decimate4_inf(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
// Sup (USB):
// x y x y x y x y / x -> 1,-2,-5,6 / y -> -0,-3,4,7
@@ -368,7 +471,7 @@ void Decimators::decimate4_sup(SampleVector::iterator* it
// Inf (LSB):
// x y x y x y x y / x -> 0,-3,-4,7 / y -> 1,2,-5,-6
// [ rotate: 0, 1, -3, 2, -4, -5, 7, -6]
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
@@ -382,10 +485,10 @@ void Decimators::decimate4_sup(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate4_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate4_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal, yimag;
+ AccuType xreal, yimag;
for (int pos = 0; pos < len - 3; pos += 4)
{
@@ -399,10 +502,10 @@ void Decimators::decimate4_sup(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate8_inf(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate8_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal[2], yimag[2];
+ AccuType xreal[2], yimag[2];
for (int pos = 0; pos < len - 15; pos += 8)
{
@@ -422,10 +525,10 @@ void Decimators::decimate8_inf(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate8_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate8_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal[2], yimag[2];
+ AccuType xreal[2], yimag[2];
for (int pos = 0; pos < len - 7; pos += 4)
{
@@ -445,10 +548,10 @@ void Decimators::decimate8_inf(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal[2], yimag[2];
+ AccuType xreal[2], yimag[2];
for (int pos = 0; pos < len - 15; pos += 8)
{
@@ -468,10 +571,10 @@ void Decimators::decimate8_sup(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate8_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate8_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal[2], yimag[2];
+ AccuType xreal[2], yimag[2];
for (int pos = 0; pos < len - 7; pos += 4)
{
@@ -491,12 +594,12 @@ void Decimators::decimate8_sup(SampleVector::iterator* it
}
}
-template
-void Decimators::decimate16_inf(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate16_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
// Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 0, 1, -3, 2, -4, -5, 7, -6]
- qint32 xreal[4], yimag[4];
+ AccuType xreal[4], yimag[4];
for (int pos = 0; pos < len - 31; )
{
@@ -519,12 +622,12 @@ void Decimators::decimate16_inf(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate16_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate16_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
// Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 0, 1, -3, 2, -4, -5, 7, -6]
- qint32 xreal[4], yimag[4];
+ AccuType xreal[4], yimag[4];
for (int pos = 0; pos < len - 15; )
{
@@ -547,12 +650,12 @@ void Decimators::decimate16_inf(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
// Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 1, 0, -2, 3, -5, -4, 6, -7]
- qint32 xreal[4], yimag[4];
+ AccuType xreal[4], yimag[4];
for (int pos = 0; pos < len - 31; )
{
@@ -575,12 +678,12 @@ void Decimators::decimate16_sup(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate16_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate16_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
// Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 1, 0, -2, 3, -5, -4, 6, -7]
- qint32 xreal[4], yimag[4];
+ AccuType xreal[4], yimag[4];
for (int pos = 0; pos < len - 15; )
{
@@ -603,10 +706,10 @@ void Decimators::decimate16_sup(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate32_inf(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate32_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal[8], yimag[8];
+ AccuType xreal[8], yimag[8];
for (int pos = 0; pos < len - 63; )
{
@@ -634,10 +737,10 @@ void Decimators::decimate32_inf(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate32_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate32_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal[8], yimag[8];
+ AccuType xreal[8], yimag[8];
for (int pos = 0; pos < len - 31; )
{
@@ -665,10 +768,10 @@ void Decimators::decimate32_inf(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal[8], yimag[8];
+ AccuType xreal[8], yimag[8];
for (int pos = 0; pos < len - 63; )
{
@@ -696,10 +799,10 @@ void Decimators::decimate32_sup(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate32_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate32_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal[8], yimag[8];
+ AccuType xreal[8], yimag[8];
for (int pos = 0; pos < len - 31; )
{
@@ -727,10 +830,10 @@ void Decimators::decimate32_sup(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate64_inf(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate64_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal[16], yimag[16];
+ AccuType xreal[16], yimag[16];
for (int pos = 0; pos < len - 127; )
{
@@ -767,10 +870,10 @@ void Decimators::decimate64_inf(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate64_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate64_inf(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal[16], yimag[16];
+ AccuType xreal[16], yimag[16];
for (int pos = 0; pos < len - 63; )
{
@@ -807,10 +910,10 @@ void Decimators::decimate64_inf(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate64_sup(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate64_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 xreal[16], yimag[16];
+ AccuType xreal[16], yimag[16];
for (int pos = 0; pos < len - 127; )
{
@@ -847,10 +950,10 @@ void Decimators::decimate64_sup(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate64_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate64_sup(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 xreal[16], yimag[16];
+ AccuType xreal[16], yimag[16];
for (int pos = 0; pos < len - 63; )
{
@@ -887,10 +990,10 @@ void Decimators::decimate64_sup(SampleVector::iterator* i
}
}
-template
-void Decimators::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
+template
+void Decimators::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
- qint32 intbuf[2];
+ AccuType intbuf[2];
for (int pos = 0; pos < len - 3; pos += 4)
{
@@ -905,14 +1008,15 @@ void Decimators::decimate2_cen(SampleVector::iterator* it
(**it).setReal(intbuf[0] >> decimation_shifts::post2);
(**it).setImag(intbuf[1] >> decimation_shifts::post2);
+
++(*it);
}
}
-template
-void Decimators::decimate2_cen(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
+template
+void Decimators::decimate2_cen(SampleVector::iterator* it, const T* bufI, const T* bufQ, qint32 len)
{
- qint32 intbuf[2];
+ AccuType intbuf[2];
for (int pos = 0; pos < len - 1; pos += 2)
{
@@ -931,10 +1035,10 @@ void Decimators