1
0
mirror of https://github.com/JvanKatwijk/qt-dab.git synced 2025-10-06 00:02:40 +02:00
Files
SDR-DAB_Qt-DAB/sources/devices/rtlsdr-handler-linux/rtlsdr-handler.cpp
2025-07-21 15:03:49 +02:00

762 lines
23 KiB
C++

#
/*
* Copyright (C) 2013 .. 2025
* Jan van Katwijk (J.vanKatwijk@gmail.com)
* Lazy Chair Computing
*
* This file is part of the Qt-DAB
*
* Qt-DAB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Qt-DAB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Qt-SDR; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This particular driver is a very simple wrapper around the
* librtlsdr. In order to keep things simple, we dynamically
* load the dll (or .so). The librtlsdr is osmocom software and all rights
* are greatly acknowledged
*/
#include <QThread>
#include "dab-constants.h"
#include "rtlsdr-handler.h"
#include "position-handler.h"
#include "rtl-dongleselect.h"
#include "rtl-sdr.h"
#include "device-exceptions.h"
#include "logger.h"
#include "settings-handler.h"
#define CORRF 0.005
#ifdef __MINGW32__
#define GETPROCADDRESS GetProcAddress
#else
#define GETPROCADDRESS dlsym
#endif
//
// Our wrapper is a simple classs
rtlsdrHandler::rtlsdrHandler (QSettings *s,
const QString &recorderVersion,
logger *theLogger): // dummy for now
_I_Buffer (8 * 1024 * 1024),
theFilter (5, 1560000 / 2, SAMPLERATE) {
int16_t deviceCount;
int32_t r;
int16_t deviceIndex;
QString temp;
int k;
char manufac [256], product [256], serial [256];
(void)theLogger;
rtlsdrSettings = s;
this -> recorderVersion = recorderVersion;
setupUi (&myFrame);
setPositionAndSize (s, &myFrame, "rtlsdrSettings");
myFrame. show ();
filtering = false;
currentDepth = value_i (rtlsdrSettings, "rtlsdrSettings",
"filterDepth", 5);
filterDepth -> setValue (currentDepth);
theFilter. resize (currentDepth);
isActive. store (false);
#ifdef __MINGW32__
const char *libraryString = "librtlsdr.dll";
#elif __linux__
// const char *libraryString = "/usr/local/lib64/librtlsdr.so";
const char *libraryString = "librtlsdr.so";
#elif __APPLE__
const char *libraryString = "librtlsdr.dylib";
#endif
phandle = new QLibrary (libraryString);
phandle -> load ();
if (!phandle -> isLoaded ()) {
throw (device_exception (std::string ("failed to open ") + std::string (libraryString)));
}
if (!load_rtlFunctions ()) {
delete (phandle);
throw (device_exception ("could not load one or more library functions"));
}
// Ok, from here we have the library functions accessible
deviceCount = this -> rtlsdr_get_device_count ();
if (deviceCount == 0) {
delete (phandle);
throw (device_exception ("No rtlsdr device found"));
}
deviceIndex = 0; // default
if (deviceCount > 1) {
rtl_dongleSelect dongleSelector;
for (deviceIndex = 0; deviceIndex < deviceCount; deviceIndex ++) {
dongleSelector.
addtoDongleList (rtlsdr_get_device_name (deviceIndex));
}
deviceIndex = dongleSelector. QDialog::exec();
}
//
// OK, now open the hardware
r = this -> rtlsdr_open (&theDevice, deviceIndex);
if (r < 0) {
delete phandle;
throw (device_exception ("Opening rtlsdr device failed"));
}
deviceModel = rtlsdr_get_device_name (deviceIndex);
deviceVersion -> setText (deviceModel);
QString tunerType = get_tunerType (rtlsdr_get_tuner_type (theDevice));
product_display -> setText (tunerType);
r = rtlsdr_set_sample_rate (theDevice, SAMPLERATE);
if (r < 0) {
delete phandle;
throw (device_exception ("Setting samplerate for rtlsdr failed"));
}
gainsCount = rtlsdr_get_tuner_gains (theDevice, nullptr);
fprintf (stderr, "Supported gain values (%d): ", gainsCount);
{ int gains [gainsCount];
gainsCount = rtlsdr_get_tuner_gains (theDevice, gains);
for (int i = gainsCount; i > 0; i--) {
fprintf (stderr, "%.1f ", gains [i - 1] / 10.0);
gainControl -> addItem (QString::number (gains [i - 1]));
}
fprintf (stderr, "\n");
}
if (rtlsdr_set_tuner_bandwidth != nullptr)
rtlsdr_set_tuner_bandwidth (theDevice, KHz (1575));
rtlsdr_set_tuner_gain_mode (theDevice, 1);
//
// See what the saved values are and restore the GUI settings
temp = value_s (rtlsdrSettings, "rtlsdrSettings",
"externalGain", "10");
k = gainControl -> findText (temp);
gainControl -> setCurrentIndex (k != -1 ? k : gainsCount / 2);
temp = value_s (rtlsdrSettings, "rtlsdrSettings",
"autogain", "autogain_on");
agcControl -> setChecked (temp == "autogain_on");
ppm_correction ->
setValue (value_i (rtlsdrSettings, "rtlsdrSettings",
"ppm_correction", 0));
save_gainSettings =
value_i (rtlsdrSettings, "rtlsdrSettings",
"save_gainSettings", 1) != 0;
(void)this -> rtlsdr_set_center_freq (theDevice, 220000000);
rtlsdr_get_usb_strings (theDevice, manufac, product, serial);
fprintf (stderr, "%s %s %s\n",
manufac, product, serial);
// all sliders/values are set to previous values, now do the settings
// based on these slider values
if (agcControl -> isChecked ())
rtlsdr_set_agc_mode (theDevice, 1);
else
rtlsdr_set_agc_mode (theDevice, 0);
rtlsdr_set_tuner_gain (theDevice,
gainControl -> currentText (). toInt ());
set_ppmCorrection (ppm_correction -> value());
for (int i = 0; i < 256; i ++)
convTable [i] = (-128.0 + i) / 128.0;
// and attach the buttons/sliders to the actions
connect (gainControl,
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 2)
qOverload<const QString &>(&QComboBox::textActivated),
#else
qOverload<const QString &>(&QComboBox::activated),
#endif
this, &rtlsdrHandler::set_ExternalGain);
#if QT_VERSION >= QT_VERSION_CHECK (6, 0, 2)
connect (agcControl, &QCheckBox::checkStateChanged,
#else
connect (agcControl, &QCheckBox::stateChanged,
#endif
this, &rtlsdrHandler::set_autogain);
connect (ppm_correction, qOverload<int>(&QSpinBox::valueChanged),
this, &rtlsdrHandler::set_ppmCorrection);
connect (xml_dumpButton, &QPushButton::clicked,
this, &rtlsdrHandler::set_xmlDump);
connect (iq_dumpButton, &QPushButton::clicked,
this, &rtlsdrHandler::set_iqDump);
#if QT_VERSION >= QT_VERSION_CHECK (6, 0, 2)
connect (biasControl, &QCheckBox::checkStateChanged,
#else
connect (biasControl, &QCheckBox::stateChanged,
#endif
this, &rtlsdrHandler::set_biasControl);
#if QT_VERSION >= QT_VERSION_CHECK (6, 0, 2)
connect (filterSelector, &QCheckBox::checkStateChanged,
#else
connect (filterSelector, &QCheckBox::stateChanged,
#endif
this, &rtlsdrHandler::set_filter);
//
// and for saving/restoring the gain setting:
connect (this, &rtlsdrHandler::new_gainIndex,
gainControl, &QComboBox::setCurrentIndex);
connect (this, &rtlsdrHandler::new_agcSetting,
agcControl, &QCheckBox::setChecked);
iqDumper = nullptr;
iq_dumping. store (false);
xml_dumping. store (false);
}
rtlsdrHandler::~rtlsdrHandler () {
stopReader ();
if (!workerHandle. isNull ()) {
rtlsdr_cancel_async (theDevice);
while (!workerHandle -> isFinished())
usleep (200);
_I_Buffer. FlushRingBuffer();
workerHandle. reset ();
}
storeWidgetPosition (rtlsdrSettings, &myFrame, "rtlsdrSettings");
QString gainText = gainControl -> currentText ();
store (rtlsdrSettings, "er;sdrSettings",
"externalGain", gainText);
store (rtlsdrSettings, "rtlsdrSettings",
"autogain", agcControl -> isChecked () ? 1 : 0);
store (rtlsdrSettings, "rtlsdrSettings",
"ppm_correction", ppm_correction -> value());
store (rtlsdrSettings, "rtlsdrSettings",
"filterDepth", filterDepth -> value ());
rtlsdrSettings -> sync ();
if (!xmlWriter. isNull ())
xmlWriter. reset ();
myFrame. hide ();
usleep (1000);
rtlsdr_close (theDevice);
delete phandle;
}
//
void rtlsdrHandler::set_filter (int c) {
(void)c;
filtering = filterSelector -> isChecked ();
}
bool rtlsdrHandler::restartReader (int32_t freq, int skipped) {
(void)(this -> rtlsdr_set_center_freq (theDevice, freq));
if (save_gainSettings)
update_gainSettings (freq / MHz (1));
lastFrequency = freq;
this -> toSkip = skipped;
set_autogain (agcControl -> isChecked ());
set_ExternalGain (gainControl -> currentText ());
if (workerHandle. isNull ()) {
// reset endpoint
(void)this -> rtlsdr_reset_buffer (theDevice);
workerHandle. reset (new dll_driver (this));
fprintf (stderr, "worker handler started\n");
}
_I_Buffer. FlushRingBuffer();
isActive. store (true);
return true;
}
void rtlsdrHandler::stopReader () {
if (workerHandle. isNull ())
return;
isActive. store (false);
this -> rtlsdr_cancel_async (theDevice);
this -> rtlsdr_reset_buffer (theDevice);
if (!workerHandle. isNull ()) {
while (!workerHandle -> isFinished())
usleep(100);
_I_Buffer.FlushRingBuffer ();
workerHandle. reset ();
}
close_xmlDump();
fprintf (stderr, "workerhandler stopped\n");
close_xmlDump ();
if (save_gainSettings)
record_gainSettings ((int32_t)(this -> rtlsdr_get_center_freq (theDevice)) / MHz (1));
}
//
// when selecting the gain from a table, use the table value
void rtlsdrHandler::set_ExternalGain (const QString &gain) {
rtlsdr_set_tuner_gain (theDevice, gain. toInt());
}
//
void rtlsdrHandler::set_autogain (int dummy) {
(void)dummy;
rtlsdr_set_agc_mode (theDevice, agcControl -> isChecked () ? 1 : 0);
rtlsdr_set_tuner_gain (theDevice,
gainControl -> currentText (). toInt ());
}
//
void rtlsdrHandler::set_biasControl (int dummy) {
(void)dummy;
if (rtlsdr_set_bias_tee != nullptr)
rtlsdr_set_bias_tee (theDevice, biasControl -> isChecked () ? 1 : 0);
}
// correction is in Hz
void rtlsdrHandler::set_ppmCorrection (int32_t ppm) {
this -> rtlsdr_set_freq_correction (theDevice, ppm);
}
int32_t rtlsdrHandler::getSamples (std::complex<float> *V, int32_t size) {
if (!isActive. load ())
return 0;
return _I_Buffer. getDataFromBuffer (V, size);
}
int32_t rtlsdrHandler::Samples () {
if (!isActive. load ())
return 0;
return _I_Buffer. GetRingBufferReadAvailable ();
}
//
bool rtlsdrHandler::load_rtlFunctions() {
//
// link the required procedures
rtlsdr_open = (pfnrtlsdr_open) phandle -> resolve ("rtlsdr_open");
if (rtlsdr_open == nullptr) {
fprintf (stderr, "Could not find rtlsdr_open\n");
return false;
}
rtlsdr_close = (pfnrtlsdr_close) phandle -> resolve ("rtlsdr_close");
if (rtlsdr_close == nullptr) {
fprintf (stderr, "Could not find rtlsdr_close\n");
return false;
}
rtlsdr_get_usb_strings =
(pfnrtlsdr_get_usb_strings)
phandle -> resolve ("rtlsdr_get_usb_strings");
if (rtlsdr_get_usb_strings == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_usb_strings\n");
return false;
}
rtlsdr_set_sample_rate =
(pfnrtlsdr_set_sample_rate)
phandle -> resolve ("rtlsdr_set_sample_rate");
if (rtlsdr_set_sample_rate == nullptr) {
fprintf (stderr, "Could not find rtlsdr_set_sample_rate\n");
return false;
}
rtlsdr_get_sample_rate =
(pfnrtlsdr_get_sample_rate)
phandle -> resolve ("rtlsdr_get_sample_rate");
if (rtlsdr_get_sample_rate == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_sample_rate\n");
return false;
}
rtlsdr_get_tuner_gains =
(pfnrtlsdr_get_tuner_gains)
phandle -> resolve ("rtlsdr_get_tuner_gains");
if (rtlsdr_get_tuner_gains == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_tuner_gains\n");
return false;
}
rtlsdr_get_tuner_type =
(pfnrtlsdr_get_tuner_type)
phandle -> resolve ("rtlsdr_get_tuner_type");
if (rtlsdr_get_tuner_type == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_tuner_type\n");
return false;
}
rtlsdr_set_tuner_gain_mode =
(pfnrtlsdr_set_tuner_gain_mode)
phandle -> resolve ("rtlsdr_set_tuner_gain_mode");
if (rtlsdr_set_tuner_gain_mode == nullptr) {
fprintf (stderr, "Could not find rtlsdr_set_tuner_gain_mode\n");
return false;
}
rtlsdr_set_agc_mode =
(pfnrtlsdr_set_agc_mode)
phandle -> resolve ("rtlsdr_set_agc_mode");
if (rtlsdr_set_agc_mode == nullptr) {
fprintf (stderr, "Could not find rtlsdr_set_agc_mode\n");
return false;
}
rtlsdr_set_tuner_gain =
(pfnrtlsdr_set_tuner_gain)
phandle -> resolve ("rtlsdr_set_tuner_gain");
if (rtlsdr_set_tuner_gain == nullptr) {
fprintf (stderr, "Cound not find rtlsdr_set_tuner_gain\n");
return false;
}
rtlsdr_get_tuner_gain =
(pfnrtlsdr_get_tuner_gain)
phandle -> resolve ("rtlsdr_get_tuner_gain");
if (rtlsdr_get_tuner_gain == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_tuner_gain\n");
return false;
}
rtlsdr_set_center_freq =
(pfnrtlsdr_set_center_freq)
phandle -> resolve ("rtlsdr_set_center_freq");
if (rtlsdr_set_center_freq == nullptr) {
fprintf (stderr, "Could not find rtlsdr_set_center_freq\n");
return false;
}
rtlsdr_get_center_freq =
(pfnrtlsdr_get_center_freq)
phandle -> resolve ("rtlsdr_get_center_freq");
if (rtlsdr_get_center_freq == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_center_freq\n");
return false;
}
rtlsdr_reset_buffer =
(pfnrtlsdr_reset_buffer)
phandle -> resolve ("rtlsdr_reset_buffer");
if (rtlsdr_reset_buffer == nullptr) {
fprintf (stderr, "Could not find rtlsdr_reset_buffer\n");
return false;
}
rtlsdr_read_async =
(pfnrtlsdr_read_async)
phandle -> resolve ("rtlsdr_read_async");
if (rtlsdr_read_async == nullptr) {
fprintf (stderr, "Cound not find rtlsdr_read_async\n");
return false;
}
rtlsdr_get_device_count =
(pfnrtlsdr_get_device_count)
phandle -> resolve ("rtlsdr_get_device_count");
if (rtlsdr_get_device_count == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_device_count\n");
return false;
}
rtlsdr_cancel_async =
(pfnrtlsdr_cancel_async)
phandle -> resolve ("rtlsdr_cancel_async");
if (rtlsdr_cancel_async == nullptr) {
fprintf (stderr, "Could not find rtlsdr_cancel_async\n");
return false;
}
rtlsdr_set_direct_sampling =
(pfnrtlsdr_set_direct_sampling)
phandle -> resolve ("rtlsdr_set_direct_sampling");
if (rtlsdr_set_direct_sampling == nullptr) {
fprintf (stderr, "Could not find rtlsdr_set_direct_sampling\n");
return false;
}
rtlsdr_set_freq_correction =
(pfnrtlsdr_set_freq_correction)
phandle -> resolve ("rtlsdr_set_freq_correction");
if (rtlsdr_set_freq_correction == nullptr) {
fprintf (stderr, "Could not find rtlsdr_set_freq_correction\n");
return false;
}
rtlsdr_get_device_name =
(pfnrtlsdr_get_device_name)
phandle -> resolve ("rtlsdr_get_device_name");
if (rtlsdr_get_device_name == nullptr) {
fprintf (stderr, "Could not find rtlsdr_get_device_name\n");
return false;
}
rtlsdr_set_tuner_bandwidth =
(pfnrtlsdr_set_center_freq)
phandle -> resolve ("rtlsdr_set_tuner_bandwidth");
if (rtlsdr_set_tuner_bandwidth == nullptr) {
fprintf (stderr, "no support for tuner bandwidth\n");
// nullpointer - if function is not available - is handled
}
rtlsdr_set_bias_tee =
(pfnrtlsdr_set_bias_tee)
phandle -> resolve ("rtlsdr_set_bias_tee");
if (rtlsdr_set_bias_tee == nullptr)
fprintf (stderr, "biasControl will not work\n");
// nullpointer - if function is not available - is handled
//
fprintf (stderr, "OK, functions seem to be loaded\n");
return true;
}
void rtlsdrHandler::resetBuffer() {
_I_Buffer. FlushRingBuffer();
}
int16_t rtlsdrHandler::maxGain() {
return gainsCount;
}
int16_t rtlsdrHandler::bitDepth() {
return 8;
}
QString rtlsdrHandler::deviceName () {
return deviceModel;
}
void rtlsdrHandler::set_iqDump () {
if (xmlWriter != nullptr)
return;
if (iqDumper == nullptr) {
if (setup_iqDump ()) {
xml_dumpButton -> hide ();
}
}
else {
close_iqDump ();
xml_dumpButton -> show ();
}
}
bool rtlsdrHandler::setup_iqDump () {
QString fileName = QFileDialog::getSaveFileName (nullptr,
tr ("Save file ..."),
QDir::homePath(),
fileName = QDir::toNativeSeparators (fileName));
iqDumper = fopen (fileName. toUtf8 (). data (), "wb");
if (iqDumper == nullptr)
return false;
iq_dumpButton -> setText ("writing raw file");
iq_dumping. store (true);
return true;
}
void rtlsdrHandler::close_iqDump () {
if (iqDumper == nullptr) // this can happen !!
return;
iq_dumping. store (false);
fclose (iqDumper);
iq_dumpButton -> setText ("Dump to raw");
iqDumper = nullptr;
}
void rtlsdrHandler::set_xmlDump () {
if (iqDumper != nullptr)
return;
if (!xml_dumping. load ()) {
if (setup_xmlDump (false))
iq_dumpButton -> hide ();
}
else {
close_xmlDump ();
iq_dumpButton -> show ();
}
}
void rtlsdrHandler::startDump () {
setup_xmlDump (true);
iq_dumpButton -> hide ();
}
void rtlsdrHandler::stopDump () {
close_xmlDump ();
iq_dumpButton -> show ();
}
static inline
bool isValid (QChar c) {
return c. isLetterOrNumber () || (c == '-');
}
bool rtlsdrHandler::setup_xmlDump (bool direct) {
QString channel = rtlsdrSettings -> value ("channel", "xx").
toString ();
try {
xmlWriter. reset (new xml_fileWriter (rtlsdrSettings,
channel,
8,
"uint8",
SAMPLERATE,
lastFrequency,
rtlsdr_get_tuner_gain (theDevice),
"RTLSDR",
deviceModel,
recorderVersion,
direct));
} catch (...) {
return false;
}
xml_dumpButton -> setText ("writing xml file");
xml_dumping. store (true);
return true;
}
void rtlsdrHandler::close_xmlDump () {
if (xmlWriter == nullptr)
return;
usleep (1000);
xmlWriter -> computeHeader ();
xmlWriter. reset ();
xml_dumpButton -> setText ("Dump to xml");
xml_dumping. store (false);
}
////////////////////////////////////////////////////////////////////////
//
// the frequency (the MHz component) is used as key
//
void rtlsdrHandler::record_gainSettings (int freq) {
QString gain = gainControl -> currentText ();
int agc = agcControl -> isChecked () ? 1 : 0;
QString theValue = gain + ":" + QString::number (agc);
QString freqVal = QString::number (freq);
store (rtlsdrSettings, "rtlsdrSettings", freqVal, theValue);
}
void rtlsdrHandler::update_gainSettings (int freq) {
int agc;
QString theValue = "";
QString freqVal = QString::number (freq);
theValue = value_s (rtlsdrSettings, "rtlsdrSettings",
freqVal, theValue);
if (theValue == QString (""))
return; // or set some defaults here
QStringList result = theValue. split (":");
if (result. size () != 2) // should not happen
return;
QString temp = result. at (0);
agc = result. at (1). toInt ();
int k = gainControl -> findText (temp);
if (k != -1) {
gainControl -> blockSignals (true);
new_gainIndex (k);
while (gainControl -> currentText () != temp)
usleep (1000);
gainControl -> blockSignals (false);
}
agcControl -> blockSignals (true);
new_agcSetting (agc == 1);
while (agcControl -> isChecked () != (agc == 1))
usleep (1000);
set_autogain (agcControl -> isChecked ());
agcControl -> blockSignals (false);
}
#define IQ_BUFSIZE 4096
void rtlsdrHandler::processBuffer (uint8_t *buf, uint32_t len) {
float sumI = 0;
float sumQ = 0;
auto *tempBuf = dynVec (std::complex<float>, len / 2);
static uint8_t dumpBuffer [2 * IQ_BUFSIZE];
static int iqTeller = 0;
if (!isActive. load ())
return;
if (toSkip > 0) {
toSkip -= len / 2;
return;
}
if (xml_dumping. load ())
xmlWriter -> add ((std::complex<uint8_t> *)buf, len / 2);
if (iq_dumping. load ()) {
for (uint32_t i = 0; i < len / 2; i ++) {
dumpBuffer [2 * iqTeller] = buf [2 * i];
dumpBuffer [2 * iqTeller + 1] = buf [2 * i + 1];
iqTeller ++;
if (iqTeller >= IQ_BUFSIZE) {
fwrite (dumpBuffer, 2, IQ_BUFSIZE, iqDumper);
iqTeller = 0;
}
}
}
if ((filtering) && (filterDepth -> value () != currentDepth)) {
currentDepth = filterDepth -> value ();
theFilter. resize (currentDepth);
}
float dcI = m_dcI;
float dcQ = m_dcQ;
for (uint32_t i = 0; i < len / 2; i ++) {
float tempI = convTable [buf [2 * i]];
float tempQ = convTable [buf [2 * i + 1]];
sumI += tempI;
sumQ += tempQ;
tempBuf [i] = std::complex<float> (tempI, tempQ);
if (filtering)
tempBuf [i] = theFilter. Pass (tempBuf [i]);
}
// calculate correction values for next input buffer
m_dcI = sumI / (len / 2) * CORRF + (1 - CORRF) * dcI;
m_dcQ = sumQ / (len / 2) * CORRF + (1 - CORRF) * dcQ;
int ovf = _I_Buffer. GetRingBufferWriteAvailable () - len / 2;
if (ovf < 0)
(void)_I_Buffer. putDataIntoBuffer (tempBuf, len / 2 + ovf);
else
(void)_I_Buffer. putDataIntoBuffer (tempBuf, len / 2);
reportOverflow (ovf < 0);
}
QString rtlsdrHandler::get_tunerType (int tunerType) {
switch (tunerType) {
case RTLSDR_TUNER_E4000:
return "E4000";
case RTLSDR_TUNER_FC0012:
return "FC0012";
case RTLSDR_TUNER_FC0013:
return "FC0013";
case RTLSDR_TUNER_FC2580:
return "FC2580";
case RTLSDR_TUNER_R820T:
return "R820T";
break;
case RTLSDR_TUNER_R828D:
return "R828D";
default:
return "unknown";
}
}
void rtlsdrHandler::reportOverflow (bool ovf) {
static bool theOvf = true;
if (ovf && !theOvf){
overflowLabel -> setText ("Overload");
overflowLabel -> setStyleSheet ("QLabel {background-color : red; \
color: white}");
theOvf = true;
}
else
if (!ovf && theOvf) { // space in the buffer is sufficient
overflowLabel -> setStyleSheet("QLabel {background-color : green; \
color: white}");
theOvf = false;
}
else
theOvf = ovf;
}