1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-17 05:41:56 -05:00

Frequency tracker (1)

This commit is contained in:
f4exb 2019-05-04 01:55:58 +02:00
parent aa60776795
commit b4b157a9a4
30 changed files with 3601 additions and 22 deletions

View File

@ -10,6 +10,7 @@ add_subdirectory(demodwfm)
add_subdirectory(chanalyzer) add_subdirectory(chanalyzer)
add_subdirectory(demodatv) add_subdirectory(demodatv)
add_subdirectory(localsink) add_subdirectory(localsink)
add_subdirectory(freqtracker)
if(LIBDSDCC_FOUND AND LIBMBE_FOUND) if(LIBDSDCC_FOUND AND LIBMBE_FOUND)
add_subdirectory(demoddsd) add_subdirectory(demoddsd)

View File

@ -0,0 +1,51 @@
project(freqtracker)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(freqtracker_SOURCES
freqtracker.cpp
freqtrackergui.cpp
freqtrackersettings.cpp
freqtrackerplugin.cpp
)
set(freqtracker_HEADERS
freqtracker.h
freqtrackergui.h
freqtrackersettings.h
freqtrackerplugin.h
)
set(freqtracker_FORMS
freqtrackergui.ui
)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
)
#include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
#qt5_wrap_cpp(nfm_HEADERS_MOC ${nfm_HEADERS})
qt5_wrap_ui(freqtracker_FORMS_HEADERS ${freqtracker_FORMS})
add_library(freqtracker SHARED
${freqtracker_SOURCES}
${freqtracker_HEADERS_MOC}
${freqtracker_FORMS_HEADERS}
)
target_link_libraries(freqtracker
${QT_LIBRARIES}
sdrbase
sdrgui
)
target_link_libraries(freqtracker Qt5::Core Qt5::Widgets)
install(TARGETS freqtracker DESTINATION lib/plugins/channelrx)

View File

@ -0,0 +1,585 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "freqtracker.h"
#include <QTime>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QBuffer>
#include <stdio.h>
#include <complex.h>
#include "SWGChannelSettings.h"
#include "SWGFreqTrackerSettings.h"
#include "SWGChannelReport.h"
#include "SWGFreqTrackerReport.h"
#include "dsp/downchannelizer.h"
#include "audio/audiooutput.h"
#include "dsp/dspengine.h"
#include "dsp/threadedbasebandsamplesink.h"
#include "dsp/dspcommands.h"
#include "dsp/fftfilt.h"
#include "device/devicesourceapi.h"
#include "util/db.h"
#include "util/stepfunctions.h"
MESSAGE_CLASS_DEFINITION(FreqTracker::MsgConfigureFreqTracker, Message)
MESSAGE_CLASS_DEFINITION(FreqTracker::MsgSampleRateNotification, Message)
MESSAGE_CLASS_DEFINITION(FreqTracker::MsgConfigureChannelizer, Message)
const QString FreqTracker::m_channelIdURI = "sdrangel.channel.freqtracker";
const QString FreqTracker::m_channelId = "FreqTracker";
const int FreqTracker::m_udpBlockSize = 512;
FreqTracker::FreqTracker(DeviceSourceAPI *deviceAPI) :
ChannelSinkAPI(m_channelIdURI),
m_deviceAPI(deviceAPI),
m_deviceSampleRate(48000),
m_inputSampleRate(48000),
m_inputFrequencyOffset(0),
m_channelSampleRate(48000),
m_running(false),
m_squelchOpen(false),
m_magsqSum(0.0f),
m_magsqPeak(0.0f),
m_magsqCount(0),
m_settingsMutex(QMutex::Recursive)
{
setObjectName(m_channelId);
m_magsq = 0.0;
m_channelizer = new DownChannelizer(this);
m_threadedChannelizer = new ThreadedBasebandSampleSink(m_channelizer, this);
m_deviceAPI->addThreadedSink(m_threadedChannelizer);
m_deviceAPI->addChannelAPI(this);
m_pll.computeCoefficients(0.05, 0.707, 1000);
m_networkManager = new QNetworkAccessManager();
connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
}
FreqTracker::~FreqTracker()
{
disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
delete m_networkManager;
m_deviceAPI->removeChannelAPI(this);
m_deviceAPI->removeThreadedSink(m_threadedChannelizer);
delete m_threadedChannelizer;
delete m_channelizer;
}
void FreqTracker::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst)
{
(void) firstOfBurst;
Complex ci;
if (!m_running) {
return;
}
m_settingsMutex.lock();
for (SampleVector::const_iterator it = begin; it != end; ++it)
{
Complex c(it->real(), it->imag());
c *= m_nco.nextIQ();
if (m_interpolatorDistance < 1.0f) // interpolate
{
processOneSample(ci);
while (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
{
processOneSample(ci);
}
m_interpolatorDistanceRemain += m_interpolatorDistance;
}
else // decimate
{
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
{
processOneSample(ci);
m_interpolatorDistanceRemain += m_interpolatorDistance;
}
}
}
m_settingsMutex.unlock();
}
void FreqTracker::processOneSample(Complex &ci)
{
Real re = ci.real() / SDR_RX_SCALEF;
Real im = ci.imag() / SDR_RX_SCALEF;
Real magsq = re*re + im*im;
m_movingAverage(magsq);
m_magsq = m_movingAverage.asDouble();
m_magsqSum += magsq;
if (magsq > m_magsqPeak)
{
m_magsqPeak = magsq;
}
m_magsqCount++;
if (m_magsq < m_squelchLevel)
{
if (m_squelchCount > 0) {
m_squelchCount--;
}
}
else
{
if (m_squelchCount < m_channelSampleRate / 10) {
m_squelchCount++;
}
}
qint16 sample;
m_squelchOpen = (m_squelchCount >= m_channelSampleRate / 20);
if (m_squelchOpen)
{
Real demod;
}
else
{
sample = 0;
}
}
void FreqTracker::start()
{
qDebug("FreqTracker::start");
m_squelchCount = 0;
m_running = true;
}
void FreqTracker::stop()
{
qDebug("FreqTracker::stop");
m_running = false;
}
bool FreqTracker::handleMessage(const Message& cmd)
{
if (DSPSignalNotification::match(cmd))
{
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
m_deviceSampleRate = notif.getSampleRate();
qDebug() << "FreqTracker::handleMessage: DSPSignalNotification:"
<< " m_deviceSampleRate: " << m_deviceSampleRate
<< " centerFrequency: " << notif.getCenterFrequency();
configureChannelizer();
}
else if (DownChannelizer::MsgChannelizerNotification::match(cmd))
{
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;
m_inputSampleRate = notif.getSampleRate();
m_inputFrequencyOffset = notif.getFrequencyOffset();
qDebug() << "FreqTracker::handleMessage: MsgChannelizerNotification:"
<< " inputSampleRate: " << m_inputSampleRate
<< " inputFrequencyOffset: " << m_inputFrequencyOffset;
setInterpolator();
return true;
}
else if (MsgConfigureFreqTracker::match(cmd))
{
MsgConfigureFreqTracker& cfg = (MsgConfigureFreqTracker&) cmd;
qDebug() << "FreqTracker::handleMessage: MsgConfigureFreqTracker";
applySettings(cfg.getSettings(), cfg.getForce());
return true;
}
else
{
return false;
}
}
void FreqTracker::applySettings(const FreqTrackerSettings& settings, bool force)
{
qDebug() << "FreqTracker::applySettings:"
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
<< " m_rfBandwidth: " << settings.m_rfBandwidth
<< " m_log2Decim: " << settings.m_log2Decim
<< " m_squelch: " << settings.m_squelch
<< " m_rgbColor: " << settings.m_rgbColor
<< " m_title: " << settings.m_title
<< " m_tracking: " << settings.m_tracking
<< " m_trackerType: " << settings.m_trackerType
<< " m_pllPskOrder: " << settings.m_pllPskOrder
<< " m_rrc: " << settings.m_rrc
<< " m_rrcRolloff: " << settings.m_rrcRolloff
<< " m_useReverseAPI: " << settings.m_useReverseAPI
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
<< " m_reverseAPIPort: " << settings.m_reverseAPIPort
<< " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
<< " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
<< " force: " << force;
QList<QString> reverseAPIKeys;
bool updateChannelizer = false;
if ((m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset) || force)
{
reverseAPIKeys.append("inputFrequencyOffset");
updateChannelizer = true;
}
if ((m_settings.m_log2Decim != settings.m_log2Decim) || force)
{
reverseAPIKeys.append("log2Decim");
updateChannelizer = true;
}
if ((m_settings.m_rfBandwidth != settings.m_rfBandwidth) || force) {
reverseAPIKeys.append("rfBandwidth");
}
if ((m_settings.m_rfBandwidth != settings.m_rfBandwidth)
&& (m_settings.m_log2Decim == settings.m_log2Decim)
&& (m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset)
&& !force)
{
setInterpolator();
}
if ((m_settings.m_squelch != settings.m_squelch) || force)
{
m_squelchLevel = CalcDb::powerFromdB(settings.m_squelch);
reverseAPIKeys.append("squelch");
}
if ((m_settings.m_rgbColor != settings.m_rgbColor) || force) {
reverseAPIKeys.append("rgbColor");
}
if ((m_settings.m_title != settings.m_title) || force) {
reverseAPIKeys.append("title");
}
if ((m_settings.m_tracking != settings.m_tracking) || force) {
reverseAPIKeys.append("tracking");
}
if ((m_settings.m_trackerType != settings.m_trackerType) || force) {
reverseAPIKeys.append("trackerType");
}
if ((m_settings.m_pllPskOrder != settings.m_pllPskOrder) || force) {
reverseAPIKeys.append("pllPskOrder");
}
if ((m_settings.m_rrc != settings.m_rrc) || force) {
reverseAPIKeys.append("rrc");
}
if ((m_settings.m_rrcRolloff != settings.m_rrcRolloff) || force) {
reverseAPIKeys.append("rrcRolloff");
}
if (settings.m_useReverseAPI)
{
bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
(m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
(m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
(m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
(m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
}
m_settings = settings;
if (updateChannelizer)
{
configureChannelizer();
}
}
void FreqTracker::setInterpolator()
{
m_settingsMutex.lock();
m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_channelSampleRate;
m_bandpass.create(301, m_channelSampleRate, 300.0, m_settings.m_rfBandwidth / 2.0f);
m_settingsMutex.unlock();
}
void FreqTracker::configureChannelizer()
{
qDebug() << "FreqTracker::configureChannelizer:"
<< " sampleRate: " << m_deviceSampleRate / (1<<m_settings.m_log2Decim)
<< " inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
m_deviceSampleRate / (1<<m_settings.m_log2Decim),
m_settings.m_inputFrequencyOffset);
if (m_guiMessageQueue)
{
MsgSampleRateNotification *msg = MsgSampleRateNotification::create(m_deviceSampleRate / (1<<m_settings.m_log2Decim));
m_guiMessageQueue->push(msg);
}
}
QByteArray FreqTracker::serialize() const
{
return m_settings.serialize();
}
bool FreqTracker::deserialize(const QByteArray& data)
{
if (m_settings.deserialize(data))
{
MsgConfigureFreqTracker *msg = MsgConfigureFreqTracker::create(m_settings, true);
m_inputMessageQueue.push(msg);
return true;
}
else
{
m_settings.resetToDefaults();
MsgConfigureFreqTracker *msg = MsgConfigureFreqTracker::create(m_settings, true);
m_inputMessageQueue.push(msg);
return false;
}
}
int FreqTracker::webapiSettingsGet(
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage)
{
(void) errorMessage;
response.setFreqTrackerSettings(new SWGSDRangel::SWGFreqTrackerSettings());
response.getFreqTrackerSettings()->init();
webapiFormatChannelSettings(response, m_settings);
return 200;
}
int FreqTracker::webapiSettingsPutPatch(
bool force,
const QStringList& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage)
{
(void) errorMessage;
FreqTrackerSettings settings = m_settings;
bool frequencyOffsetChanged = false;
if (channelSettingsKeys.contains("inputFrequencyOffset"))
{
settings.m_inputFrequencyOffset = response.getFreqTrackerSettings()->getInputFrequencyOffset();
frequencyOffsetChanged = true;
}
if (channelSettingsKeys.contains("rfBandwidth")) {
settings.m_rfBandwidth = response.getFreqTrackerSettings()->getRfBandwidth();
}
if (channelSettingsKeys.contains("log2Decim")) {
settings.m_log2Decim = response.getFreqTrackerSettings()->getLog2Decim();
}
if (channelSettingsKeys.contains("squelch")) {
settings.m_squelch = response.getFreqTrackerSettings()->getSquelch();
}
if (channelSettingsKeys.contains("rgbColor")) {
settings.m_rgbColor = response.getFreqTrackerSettings()->getRgbColor();
}
if (channelSettingsKeys.contains("title")) {
settings.m_title = *response.getFreqTrackerSettings()->getTitle();
}
if (channelSettingsKeys.contains("tracking")) {
settings.m_tracking = response.getFreqTrackerSettings()->getTracking() ? 1 : 0;
}
if (channelSettingsKeys.contains("trackerType"))
{
int32_t trackerTypeCode = response.getFreqTrackerSettings()->getTrackerType();
settings.m_trackerType = trackerTypeCode < 0 ?
FreqTrackerSettings::TrackerFLL : trackerTypeCode > 1 ?
FreqTrackerSettings::TrackerPLL : (FreqTrackerSettings::TrackerType) trackerTypeCode;
}
if (channelSettingsKeys.contains("pllPskOrder")) {
settings.m_pllPskOrder = response.getFreqTrackerSettings()->getPllPskOrder();
}
if (channelSettingsKeys.contains("rrc")) {
settings.m_rrc = response.getFreqTrackerSettings()->getRrc() ? 1 : 0;
}
if (channelSettingsKeys.contains("rrcRolloff")) {
settings.m_rrcRolloff = response.getFreqTrackerSettings()->getRrcRolloff();
}
if (channelSettingsKeys.contains("useReverseAPI")) {
settings.m_useReverseAPI = response.getAmDemodSettings()->getUseReverseApi() != 0;
}
if (channelSettingsKeys.contains("reverseAPIAddress")) {
settings.m_reverseAPIAddress = *response.getAmDemodSettings()->getReverseApiAddress();
}
if (channelSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getAmDemodSettings()->getReverseApiPort();
}
if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getAmDemodSettings()->getReverseApiDeviceIndex();
}
if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
settings.m_reverseAPIChannelIndex = response.getAmDemodSettings()->getReverseApiChannelIndex();
}
MsgConfigureFreqTracker *msg = MsgConfigureFreqTracker::create(settings, force);
m_inputMessageQueue.push(msg);
if ((settings.m_log2Decim != m_settings.m_log2Decim) || frequencyOffsetChanged || force)
{
MsgConfigureChannelizer *msg = MsgConfigureChannelizer::create(
m_deviceSampleRate / (1<<settings.m_log2Decim), settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msg);
}
qDebug("FreqTracker::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureFreqTracker *msgToGUI = MsgConfigureFreqTracker::create(settings, force);
m_guiMessageQueue->push(msgToGUI);
}
webapiFormatChannelSettings(response, settings);
return 200;
}
int FreqTracker::webapiReportGet(
SWGSDRangel::SWGChannelReport& response,
QString& errorMessage)
{
(void) errorMessage;
response.setFreqTrackerReport(new SWGSDRangel::SWGFreqTrackerReport());
response.getFreqTrackerReport()->init();
webapiFormatChannelReport(response);
return 200;
}
void FreqTracker::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const FreqTrackerSettings& settings)
{
response.getFreqTrackerSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
response.getFreqTrackerSettings()->setRfBandwidth(settings.m_rfBandwidth);
response.getFreqTrackerSettings()->setRgbColor(settings.m_rgbColor);
response.getFreqTrackerSettings()->setSquelch(settings.m_squelch);
if (response.getFreqTrackerSettings()->getTitle()) {
*response.getFreqTrackerSettings()->getTitle() = settings.m_title;
} else {
response.getFreqTrackerSettings()->setTitle(new QString(settings.m_title));
}
response.getFreqTrackerSettings()->setTrackerType((int) m_settings.m_trackerType);
response.getFreqTrackerSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
if (response.getFreqTrackerSettings()->getReverseApiAddress()) {
*response.getFreqTrackerSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
} else {
response.getFreqTrackerSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
}
response.getFreqTrackerSettings()->setReverseApiPort(settings.m_reverseAPIPort);
response.getFreqTrackerSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
response.getFreqTrackerSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex);
}
void FreqTracker::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
{
double magsqAvg, magsqPeak;
int nbMagsqSamples;
getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
response.getFreqTrackerReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg));
response.getFreqTrackerReport()->setSquelch(m_squelchOpen ? 1 : 0);
response.getFreqTrackerReport()->setSampleRate(m_channelSampleRate);
response.getFreqTrackerReport()->setChannelSampleRate(m_inputSampleRate);
}
void FreqTracker::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const FreqTrackerSettings& settings, bool force)
{
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
swgChannelSettings->setTx(0);
swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet());
swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex());
swgChannelSettings->setChannelType(new QString("FreqTracker"));
swgChannelSettings->setFreqTrackerSettings(new SWGSDRangel::SWGFreqTrackerSettings());
SWGSDRangel::SWGFreqTrackerSettings *swgFreqTrackerSettings = swgChannelSettings->getFreqTrackerSettings();
// transfer data that has been modified. When force is on transfer all data except reverse API data
if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
swgFreqTrackerSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
}
if (channelSettingsKeys.contains("rfBandwidth") || force) {
swgFreqTrackerSettings->setRfBandwidth(settings.m_rfBandwidth);
}
if (channelSettingsKeys.contains("rgbColor") || force) {
swgFreqTrackerSettings->setRgbColor(settings.m_rgbColor);
}
if (channelSettingsKeys.contains("squelch") || force) {
swgFreqTrackerSettings->setSquelch(settings.m_squelch);
}
if (channelSettingsKeys.contains("title") || force) {
swgFreqTrackerSettings->setTitle(new QString(settings.m_title));
}
if (channelSettingsKeys.contains("trackerType") || force) {
swgFreqTrackerSettings->setTrackerType((int) settings.m_trackerType);
}
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
.arg(settings.m_reverseAPIAddress)
.arg(settings.m_reverseAPIPort)
.arg(settings.m_reverseAPIDeviceIndex)
.arg(settings.m_reverseAPIChannelIndex);
m_networkRequest.setUrl(QUrl(channelSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer=new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgChannelSettings->asJson().toUtf8());
buffer->seek(0);
// Always use PATCH to avoid passing reverse API settings
m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
delete swgChannelSettings;
}
void FreqTracker::networkManagerFinished(QNetworkReply *reply)
{
QNetworkReply::NetworkError replyError = reply->error();
if (replyError)
{
qWarning() << "FreqTracker::networkManagerFinished:"
<< " error(" << (int) replyError
<< "): " << replyError
<< ": " << reply->errorString();
return;
}
QString answer = reply->readAll();
answer.chop(1); // remove last \n
qDebug("FreqTracker::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
}

View File

@ -0,0 +1,242 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FREQTRACKER_H
#define INCLUDE_FREQTRACKER_H
#include <vector>
#include <QNetworkRequest>
#include <QMutex>
#include "dsp/basebandsamplesink.h"
#include "channel/channelsinkapi.h"
#include "dsp/nco.h"
#include "dsp/interpolator.h"
#include "util/movingaverage.h"
#include "dsp/agc.h"
#include "dsp/bandpass.h"
#include "dsp/lowpass.h"
#include "dsp/phaselockcomplex.h"
#include "dsp/freqlockcomplex.h"
#include "util/message.h"
#include "util/doublebufferfifo.h"
#include "freqtrackersettings.h"
class QNetworkAccessManager;
class QNetworkReply;
class DeviceSourceAPI;
class DownChannelizer;
class ThreadedBasebandSampleSink;
class fftfilt;
class FreqTracker : public BasebandSampleSink, public ChannelSinkAPI {
Q_OBJECT
public:
class MsgConfigureFreqTracker : public Message {
MESSAGE_CLASS_DECLARATION
public:
const FreqTrackerSettings& getSettings() const { return m_settings; }
bool getForce() const { return m_force; }
static MsgConfigureFreqTracker* create(const FreqTrackerSettings& settings, bool force)
{
return new MsgConfigureFreqTracker(settings, force);
}
private:
FreqTrackerSettings m_settings;
bool m_force;
MsgConfigureFreqTracker(const FreqTrackerSettings& settings, bool force) :
Message(),
m_settings(settings),
m_force(force)
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSampleRate() const { return m_sampleRate; }
int getCenterFrequency() const { return m_centerFrequency; }
static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
{
return new MsgConfigureChannelizer(sampleRate, centerFrequency);
}
private:
int m_sampleRate;
int m_centerFrequency;
MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
Message(),
m_sampleRate(sampleRate),
m_centerFrequency(centerFrequency)
{ }
};
class MsgSampleRateNotification : public Message {
MESSAGE_CLASS_DECLARATION
public:
static MsgSampleRateNotification* create(int sampleRate) {
return new MsgSampleRateNotification(sampleRate);
}
int getSampleRate() const { return m_sampleRate; }
private:
MsgSampleRateNotification(int sampleRate) :
Message(),
m_sampleRate(sampleRate)
{ }
int m_sampleRate;
};
FreqTracker(DeviceSourceAPI *deviceAPI);
~FreqTracker();
virtual void destroy() { delete this; }
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
virtual void start();
virtual void stop();
virtual bool handleMessage(const Message& cmd);
virtual void getIdentifier(QString& id) { id = objectName(); }
virtual void getTitle(QString& title) { title = m_settings.m_title; }
virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
virtual int webapiSettingsGet(
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& channelSettingsKeys,
SWGSDRangel::SWGChannelSettings& response,
QString& errorMessage);
virtual int webapiReportGet(
SWGSDRangel::SWGChannelReport& response,
QString& errorMessage);
uint32_t getSampleRate() const { return m_channelSampleRate; }
double getMagSq() const { return m_magsq; }
bool getSquelchOpen() const { return m_squelchOpen; }
bool getPllLocked() const { return (m_settings.m_trackerType == FreqTrackerSettings::TrackerPLL) && m_pll.locked(); }
Real getPllFrequency() const { return m_pll.getFreq(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples)
{
if (m_magsqCount > 0)
{
m_magsq = m_magsqSum / m_magsqCount;
m_magSqLevelStore.m_magsq = m_magsq;
m_magSqLevelStore.m_magsqPeak = m_magsqPeak;
}
avg = m_magSqLevelStore.m_magsq;
peak = m_magSqLevelStore.m_magsqPeak;
nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
m_magsqSum = 0.0f;
m_magsqPeak = 0.0f;
m_magsqCount = 0;
}
static const QString m_channelIdURI;
static const QString m_channelId;
private:
struct MagSqLevelsStore
{
MagSqLevelsStore() :
m_magsq(1e-12),
m_magsqPeak(1e-12)
{}
double m_magsq;
double m_magsqPeak;
};
enum RateState {
RSInitialFill,
RSRunning
};
DeviceSourceAPI *m_deviceAPI;
ThreadedBasebandSampleSink* m_threadedChannelizer;
DownChannelizer* m_channelizer;
FreqTrackerSettings m_settings;
int m_deviceSampleRate;
int m_inputSampleRate;
int m_inputFrequencyOffset;
uint32_t m_channelSampleRate;
bool m_running;
NCO m_nco;
PhaseLockComplex m_pll;
FreqLockComplex m_fll;
Interpolator m_interpolator;
Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain;
fftfilt* RRCFilter;
Real m_squelchLevel;
uint32_t m_squelchCount;
bool m_squelchOpen;
double m_magsq;
double m_magsqSum;
double m_magsqPeak;
int m_magsqCount;
MagSqLevelsStore m_magSqLevelStore;
MovingAverageUtil<Real, double, 16> m_movingAverage;
Bandpass<Real> m_bandpass;
static const int m_udpBlockSize;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
QMutex m_settingsMutex;
void applySettings(const FreqTrackerSettings& settings, bool force = false);
void setInterpolator();
void configureChannelizer();
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const FreqTrackerSettings& settings);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const FreqTrackerSettings& settings, bool force);
void processOneSample(Complex &ci);
private slots:
void networkManagerFinished(QNetworkReply *reply);
};
#endif // INCLUDE_FREQTRACKER_H

View File

@ -0,0 +1,52 @@
#--------------------------------------------------------
#
# Pro file for Android and Windows builds with Qt Creator
#
#--------------------------------------------------------
TEMPLATE = lib
CONFIG += plugin
QT += core gui widgets multimedia
TARGET = demodam
DEFINES += USE_SSE2=1
QMAKE_CXXFLAGS += -msse2
DEFINES += USE_SSE4_1=1
QMAKE_CXXFLAGS += -msse4.1
QMAKE_CXXFLAGS += -std=c++11
INCLUDEPATH += $$PWD
INCLUDEPATH += ../../../exports
INCLUDEPATH += ../../../sdrbase
INCLUDEPATH += ../../../sdrgui
INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client
CONFIG(Release):build_subdir = release
CONFIG(Debug):build_subdir = debug
SOURCES += amdemod.cpp\
amdemodgui.cpp\
amdemodplugin.cpp\
amdemodsettings.cpp\
amdemodssbdialog.cpp
HEADERS += amdemod.h\
amdemodgui.h\
amdemodplugin.h\
amdemodsettings.h\
amdemodssbdialog.h
FORMS += amdemodgui.ui\
amdemodssb.ui
LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase
LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui
LIBS += -L../../../swagger/$${build_subdir} -lswagger
macx {
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@rpath/
}
RESOURCES = ../../../sdrgui/resources/res.qrc

View File

@ -0,0 +1,389 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QDockWidget>
#include <QMainWindow>
#include <QDebug>
#include "freqtrackergui.h"
#include "device/devicesourceapi.h"
#include "device/deviceuiset.h"
#include "dsp/downchannelizer.h"
#include "dsp/dspengine.h"
#include "dsp/threadedbasebandsamplesink.h"
#include "ui_freqtrackergui.h"
#include "plugin/pluginapi.h"
#include "util/simpleserializer.h"
#include "util/db.h"
#include "gui/basicchannelsettingsdialog.h"
#include "dsp/dspengine.h"
#include "mainwindow.h"
#include "gui/crightclickenabler.h"
#include "gui/audioselectdialog.h"
#include "freqtracker.h"
FreqTrackerGUI* FreqTrackerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
{
FreqTrackerGUI* gui = new FreqTrackerGUI(pluginAPI, deviceUISet, rxChannel);
return gui;
}
void FreqTrackerGUI::destroy()
{
delete this;
}
void FreqTrackerGUI::setName(const QString& name)
{
setObjectName(name);
}
QString FreqTrackerGUI::getName() const
{
return objectName();
}
qint64 FreqTrackerGUI::getCenterFrequency() const {
return m_channelMarker.getCenterFrequency();
}
void FreqTrackerGUI::setCenterFrequency(qint64 centerFrequency)
{
m_channelMarker.setCenterFrequency(centerFrequency);
applySettings();
}
void FreqTrackerGUI::resetToDefaults()
{
m_settings.resetToDefaults();
displaySettings();
applySettings(true);
}
QByteArray FreqTrackerGUI::serialize() const
{
return m_settings.serialize();
}
bool FreqTrackerGUI::deserialize(const QByteArray& data)
{
if(m_settings.deserialize(data)) {
displaySettings();
applySettings(true);
return true;
} else {
resetToDefaults();
return false;
}
}
bool FreqTrackerGUI::handleMessage(const Message& message)
{
if (FreqTracker::MsgConfigureFreqTracker::match(message))
{
qDebug("FreqTrackerGUI::handleMessage: FreqTracker::MsgConfigureFreqTracker");
const FreqTracker::MsgConfigureFreqTracker& cfg = (FreqTracker::MsgConfigureFreqTracker&) message;
m_settings = cfg.getSettings();
blockApplySettings(true);
displaySettings();
blockApplySettings(false);
return true;
}
else if (FreqTracker::MsgSampleRateNotification::match(message))
{
qDebug("FreqTrackerGUI::handleMessage: FreqTracker::MsgSampleRateNotification");
const FreqTracker::MsgSampleRateNotification& cfg = (FreqTracker::MsgSampleRateNotification&) message;
m_channelSampleRate = cfg.getSampleRate();
ui->channelSampleRateText->setText(tr("%1k").arg(QString::number(m_channelSampleRate / 1000.0f, 'g', 5)));
if (m_channelSampleRate > 1000) {
ui->rfBW->setMaximum(m_channelSampleRate/100);
}
return true;
}
return false;
}
void FreqTrackerGUI::handleInputMessages()
{
Message* message;
while ((message = getInputMessageQueue()->pop()) != 0)
{
if (handleMessage(*message))
{
delete message;
}
}
}
void FreqTrackerGUI::channelMarkerChangedByCursor()
{
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
applySettings();
}
void FreqTrackerGUI::channelMarkerHighlightedByCursor()
{
setHighlighted(m_channelMarker.getHighlighted());
}
void FreqTrackerGUI::on_deltaFrequency_changed(qint64 value)
{
m_channelMarker.setCenterFrequency(value);
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
applySettings();
}
void FreqTrackerGUI::on_log2Decim_currentIndexChanged(int index)
{
m_settings.m_log2Decim = index < 0 ? 0 : index > 6 ? 6 : index;
applySettings();
}
void FreqTrackerGUI::on_rfBW_valueChanged(int value)
{
ui->rfBWText->setText(QString("%1 kHz").arg(value / 10.0, 0, 'f', 1));
m_channelMarker.setBandwidth(value * 100);
m_settings.m_rfBandwidth = value * 100;
applySettings();
}
void FreqTrackerGUI::on_tracking_toggled(bool checked)
{
if (!checked)
{
ui->tracking->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
ui->tracking->setToolTip(tr("PLL for synchronous AM"));
}
m_settings.m_tracking = checked;
applySettings();
}
void FreqTrackerGUI::on_trackerType_currentIndexChanged(int index)
{
m_settings.m_trackerType = (FreqTrackerSettings::TrackerType) index;
applySettings();
}
void FreqTrackerGUI::on_pllPskOrder_currentIndexChanged(int index)
{
m_settings.m_pllPskOrder = index;
applySettings();
}
void FreqTrackerGUI::on_rrc_toggled(bool checked)
{
m_settings.m_rrc = checked;
applySettings();
}
void FreqTrackerGUI::on_rrcRolloff_valueChanged(int value)
{
m_settings.m_rrcRolloff = value < 0 ? 0 : value > 100 ? 100 : value;
QString rolloffStr = QString::number(value/100.0, 'f', 2);
ui->rrcRolloffText->setText(rolloffStr);
applySettings();
}
void FreqTrackerGUI::on_squelch_valueChanged(int value)
{
ui->squelchText->setText(QString("%1 dB").arg(value));
m_settings.m_squelch = value;
applySettings();
}
void FreqTrackerGUI::onWidgetRolled(QWidget* widget, bool rollDown)
{
(void) widget;
(void) rollDown;
}
void FreqTrackerGUI::onMenuDialogCalled(const QPoint &p)
{
BasicChannelSettingsDialog dialog(&m_channelMarker, this);
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
dialog.setReverseAPIChannelIndex(m_settings.m_reverseAPIChannelIndex);
dialog.move(p);
dialog.exec();
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
m_settings.m_rgbColor = m_channelMarker.getColor().rgb();
m_settings.m_title = m_channelMarker.getTitle();
m_settings.m_useReverseAPI = dialog.useReverseAPI();
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
m_settings.m_reverseAPIChannelIndex = dialog.getReverseAPIChannelIndex();
setWindowTitle(m_settings.m_title);
setTitleColor(m_settings.m_rgbColor);
applySettings();
}
FreqTrackerGUI::FreqTrackerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
RollupWidget(parent),
ui(new Ui::FreqTrackerGUI),
m_pluginAPI(pluginAPI),
m_deviceUISet(deviceUISet),
m_channelMarker(this),
m_channelSampleRate(0),
m_doApplySettings(true),
m_squelchOpen(false),
m_tickCount(0)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
m_freqTracker = reinterpret_cast<FreqTracker*>(rxChannel); //new FreqTracker(m_deviceUISet->m_deviceSourceAPI);
m_freqTracker->setMessageQueueToGUI(getInputMessageQueue());
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
m_channelMarker.blockSignals(true);
m_channelMarker.setColor(Qt::yellow);
m_channelMarker.setBandwidth(5000);
m_channelMarker.setCenterFrequency(0);
m_channelMarker.setTitle("AM Demodulator");
m_channelMarker.blockSignals(false);
m_channelMarker.setVisible(true); // activate signal on the last setting only
setTitleColor(m_channelMarker.getColor());
m_settings.setChannelMarker(&m_channelMarker);
m_deviceUISet->registerRxChannelInstance(FreqTracker::m_channelIdURI, this);
m_deviceUISet->addChannelMarker(&m_channelMarker);
m_deviceUISet->addRollupWidget(this);
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
displaySettings();
applySettings(true);
}
FreqTrackerGUI::~FreqTrackerGUI()
{
m_deviceUISet->removeRxChannelInstance(this);
delete m_freqTracker; // TODO: check this: when the GUI closes it has to delete the demodulator
delete ui;
}
void FreqTrackerGUI::blockApplySettings(bool block)
{
m_doApplySettings = !block;
}
void FreqTrackerGUI::applySettings(bool force)
{
if (m_doApplySettings)
{
FreqTracker::MsgConfigureFreqTracker* message = FreqTracker::MsgConfigureFreqTracker::create( m_settings, force);
m_freqTracker->getInputMessageQueue()->push(message);
}
}
void FreqTrackerGUI::displaySettings()
{
m_channelMarker.blockSignals(true);
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
m_channelMarker.setTitle(m_settings.m_title);
m_channelMarker.blockSignals(false);
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
setTitleColor(m_settings.m_rgbColor);
setWindowTitle(m_channelMarker.getTitle());
blockApplySettings(true);
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
int displayValue = m_settings.m_rfBandwidth/100.0;
ui->rfBW->setValue(displayValue);
ui->rfBWText->setText(QString("%1 kHz").arg(displayValue / 10.0, 0, 'f', 1));
ui->squelch->setValue(m_settings.m_squelch);
ui->squelchText->setText(QString("%1 dB").arg(m_settings.m_squelch));
ui->tracking->setChecked(m_settings.m_tracking);
blockApplySettings(false);
}
void FreqTrackerGUI::leaveEvent(QEvent*)
{
m_channelMarker.setHighlighted(false);
}
void FreqTrackerGUI::enterEvent(QEvent*)
{
m_channelMarker.setHighlighted(true);
}
void FreqTrackerGUI::tick()
{
double magsqAvg, magsqPeak;
int nbMagsqSamples;
m_freqTracker->getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
double powDbAvg = CalcDb::dbPower(magsqAvg);
double powDbPeak = CalcDb::dbPower(magsqPeak);
ui->channelPowerMeter->levelChanged(
(100.0f + powDbAvg) / 100.0f,
(100.0f + powDbPeak) / 100.0f,
nbMagsqSamples);
if (m_tickCount % 4 == 0) {
ui->channelPower->setText(QString::number(powDbAvg, 'f', 1));
}
bool squelchOpen = m_freqTracker->getSquelchOpen();
if (m_settings.m_tracking)
{
if (m_freqTracker->getPllLocked()) {
ui->tracking->setStyleSheet("QToolButton { background-color : green; }");
} else {
ui->tracking->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
}
int freq = (m_freqTracker->getPllFrequency() * m_freqTracker->getSampleRate()) / (2.0*M_PI);
ui->tracking->setToolTip(tr("PLL for synchronous AM. Freq = %1 Hz").arg(freq));
}
m_tickCount++;
}

View File

@ -0,0 +1,102 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FREQTRACKERGUI_H
#define INCLUDE_FREQTRACKERGUI_H
#include <QIcon>
#include "plugin/plugininstancegui.h"
#include "gui/rollupwidget.h"
#include "dsp/channelmarker.h"
#include "dsp/movingaverage.h"
#include "util/messagequeue.h"
#include "freqtrackersettings.h"
class PluginAPI;
class DeviceUISet;
class FreqTracker;
class BasebandSampleSink;
namespace Ui {
class FreqTrackerGUI;
}
class FreqTrackerGUI : public RollupWidget, public PluginInstanceGUI {
Q_OBJECT
public:
static FreqTrackerGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
virtual void destroy();
void setName(const QString& name);
QString getName() const;
virtual qint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
public slots:
void channelMarkerChangedByCursor();
void channelMarkerHighlightedByCursor();
private:
Ui::FreqTrackerGUI* ui;
PluginAPI* m_pluginAPI;
DeviceUISet* m_deviceUISet;
ChannelMarker m_channelMarker;
FreqTrackerSettings m_settings;
int m_channelSampleRate;
bool m_doApplySettings;
FreqTracker* m_freqTracker;
bool m_squelchOpen;
uint32_t m_tickCount;
MessageQueue m_inputMessageQueue;
explicit FreqTrackerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
virtual ~FreqTrackerGUI();
void blockApplySettings(bool block);
void applySettings(bool force = false);
void displaySettings();
void leaveEvent(QEvent*);
void enterEvent(QEvent*);
private slots:
void on_deltaFrequency_changed(qint64 value);
void on_log2Decim_currentIndexChanged(int index);
void on_rfBW_valueChanged(int value);
void on_tracking_toggled(bool checked);
void on_trackerType_currentIndexChanged(int index);
void on_pllPskOrder_currentIndexChanged(int index);
void on_rrc_toggled(bool checked);
void on_rrcRolloff_valueChanged(int value);
void on_squelch_valueChanged(int value);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void handleInputMessages();
void tick();
};
#endif // INCLUDE_FREQTRACKERGUI_H

View File

@ -0,0 +1,585 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FreqTrackerGUI</class>
<widget class="RollupWidget" name="FreqTrackerGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<height>145</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>350</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Frequency Tracker</string>
</property>
<property name="statusTip">
<string>Frequency Tracker</string>
</property>
<widget class="QWidget" name="settingsContainer" native="true">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>348</width>
<height>140</height>
</rect>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="deltaFreqPowLayout">
<item>
<layout class="QHBoxLayout" name="deltaFrequencyLayout">
<item>
<widget class="QLabel" name="deltaFrequencyLabel">
<property name="minimumSize">
<size>
<width>16</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Df</string>
</property>
</widget>
</item>
<item>
<widget class="ValueDialZ" name="deltaFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Demod shift frequency from center in Hz</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="deltaUnits">
<property name="text">
<string>Hz </string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="channelPowerLayout">
<item>
<widget class="QLabel" name="channelPower">
<property name="toolTip">
<string>Channel power</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>0.0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="channelPowerUnits">
<property name="text">
<string> dB</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="signalLevelLayout">
<item>
<widget class="QLabel" name="channelPowerMeterUnits">
<property name="text">
<string>dB</string>
</property>
</widget>
</item>
<item>
<widget class="LevelMeterSignalDB" name="channelPowerMeter" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>24</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>Level meter (dB) top trace: average, bottom trace: instantaneous peak, tip: peak hold</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="rfBandwidthLayout">
<item>
<widget class="QComboBox" name="log2Decim">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Decimation factor</string>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>16</string>
</property>
</item>
<item>
<property name="text">
<string>32</string>
</property>
</item>
<item>
<property name="text">
<string>64</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="channelSampleRateText">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Channel sample rate</string>
</property>
<property name="text">
<string>00000k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rfBandwidthLabel">
<property name="text">
<string>BW</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="rfBW">
<property name="toolTip">
<string>Channel bandwidth</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>400</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rfBWText">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Channel bandwidth</string>
</property>
<property name="text">
<string>5.0 kHz</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="trackerLayout">
<item>
<widget class="QToolButton" name="tracking">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Tracking enable</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/unlocked.png</normaloff>
<normalon>:/locked.png</normalon>:/unlocked.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="trackerType">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Tracking type</string>
</property>
<item>
<property name="text">
<string>FLL</string>
</property>
</item>
<item>
<property name="text">
<string>PLL</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QComboBox" name="pllPskOrder">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>PLL PSK order (1 for CW)</string>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>16</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="rrc">
<property name="toolTip">
<string>Toggle Reverse Root Cosine filter</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/dsb.png</normaloff>:/dsb.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="rrcRolloff">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Reverse Root Cosine filter rolloff factor</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rrcRolloffText">
<property name="minimumSize">
<size>
<width>32</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Reverse Root Cosine filter rolloff factor</string>
</property>
<property name="text">
<string>0.35</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="squelchLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Sq</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="squelch">
<property name="toolTip">
<string>Squelch</string>
</property>
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>-40</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="squelchText">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>-40dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>RollupWidget</class>
<extends>QWidget</extends>
<header>gui/rollupwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LevelMeterSignalDB</class>
<extends>QWidget</extends>
<header>gui/levelmeter.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
<customwidget>
<class>ValueDialZ</class>
<extends>QWidget</extends>
<header>gui/valuedialz.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,78 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QtPlugin>
#include "plugin/pluginapi.h"
#ifndef SERVER_MODE
#include "freqtrackergui.h"
#endif
#include "freqtracker.h"
#include "freqtrackerplugin.h"
const PluginDescriptor FreqTrackerPlugin::m_pluginDescriptor = {
QString("Frequency Tracker"),
QString("4.7.0"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
QString("https://github.com/f4exb/sdrangel")
};
FreqTrackerPlugin::FreqTrackerPlugin(QObject* parent) :
QObject(parent),
m_pluginAPI(0)
{
}
const PluginDescriptor& FreqTrackerPlugin::getPluginDescriptor() const
{
return m_pluginDescriptor;
}
void FreqTrackerPlugin::initPlugin(PluginAPI* pluginAPI)
{
m_pluginAPI = pluginAPI;
// register AM demodulator
m_pluginAPI->registerRxChannel(FreqTracker::m_channelIdURI, FreqTracker::m_channelId, this);
}
#ifdef SERVER_MODE
PluginInstanceGUI* FreqTrackerPlugin::createRxChannelGUI(
DeviceUISet *deviceUISet __attribute__((unused)),
BasebandSampleSink *rxChannel __attribute__((unused)))
{
return 0;
}
#else
PluginInstanceGUI* FreqTrackerPlugin::createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
{
return FreqTrackerGUI::create(m_pluginAPI, deviceUISet, rxChannel);
}
#endif
BasebandSampleSink* FreqTrackerPlugin::createRxChannelBS(DeviceSourceAPI *deviceAPI)
{
return new FreqTracker(deviceAPI);
}
ChannelSinkAPI* FreqTrackerPlugin::createRxChannelCS(DeviceSourceAPI *deviceAPI)
{
return new FreqTracker(deviceAPI);
}

View File

@ -0,0 +1,48 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_FREQTRACKERPLUGIN_H
#define INCLUDE_FREQTRACKERPLUGIN_H
#include <QObject>
#include "plugin/plugininterface.h"
class DeviceUISet;
class BasebandSampleSink;
class FreqTrackerPlugin : public QObject, PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID "sdrangel.channel.freqtracker")
public:
explicit FreqTrackerPlugin(QObject* parent = NULL);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
virtual PluginInstanceGUI* createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
virtual BasebandSampleSink* createRxChannelBS(DeviceSourceAPI *deviceAPI);
virtual ChannelSinkAPI* createRxChannelCS(DeviceSourceAPI *deviceAPI);
private:
static const PluginDescriptor m_pluginDescriptor;
PluginAPI* m_pluginAPI;
};
#endif // INCLUDE_FREQTRACKERPLUGIN_H

View File

@ -0,0 +1,142 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QColor>
#include "dsp/dspengine.h"
#include "util/simpleserializer.h"
#include "settings/serializable.h"
#include "freqtrackersettings.h"
FreqTrackerSettings::FreqTrackerSettings() :
m_channelMarker(0)
{
resetToDefaults();
}
void FreqTrackerSettings::resetToDefaults()
{
m_inputFrequencyOffset = 0;
m_rfBandwidth = 6000;
m_log2Decim = 0;
m_squelch = -40.0;
m_rgbColor = QColor(200, 244, 66).rgb();
m_title = "Frequency Tracker";
m_tracking = false;
m_trackerType = TrackerFLL;
m_pllPskOrder = 1;
m_rrc = false;
m_rrcRolloff = 35;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888;
m_reverseAPIDeviceIndex = 0;
m_reverseAPIChannelIndex = 0;
}
QByteArray FreqTrackerSettings::serialize() const
{
SimpleSerializer s(1);
s.writeS32(1, m_inputFrequencyOffset);
s.writeS32(2, m_rfBandwidth/100);
s.writeU32(3, m_log2Decim);
s.writeS32(5, m_squelch);
if (m_channelMarker) {
s.writeBlob(6, m_channelMarker->serialize());
}
s.writeU32(7, m_rgbColor);
s.writeString(9, m_title);
s.writeBool(10, m_tracking);
s.writeS32(12, (int) m_trackerType);
s.writeU32(13, m_pllPskOrder);
s.writeBool(14, m_rrc);
s.writeU32(15, m_rrcRolloff);
s.writeBool(16, m_useReverseAPI);
s.writeString(17, m_reverseAPIAddress);
s.writeU32(18, m_reverseAPIPort);
s.writeU32(19, m_reverseAPIDeviceIndex);
s.writeU32(20, m_reverseAPIChannelIndex);
return s.final();
}
bool FreqTrackerSettings::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if(!d.isValid())
{
resetToDefaults();
return false;
}
if(d.getVersion() == 1)
{
QByteArray bytetmp;
qint32 tmp;
uint32_t utmp;
QString strtmp;
d.readS32(1, &m_inputFrequencyOffset, 0);
d.readS32(2, &tmp, 4);
m_rfBandwidth = 100 * tmp;
d.readU32(3, &utmp, 0);
m_log2Decim = utmp > 6 ? 6 : utmp;
d.readS32(4, &tmp, 20);
d.readS32(5, &tmp, -40);
m_squelch = tmp;
d.readBlob(6, &bytetmp);
if (m_channelMarker) {
m_channelMarker->deserialize(bytetmp);
}
d.readU32(7, &m_rgbColor, QColor(200, 244, 66).rgb());
d.readString(9, &m_title, "Frequency Tracker");
d.readBool(10, &m_tracking, false);
d.readS32(12, &tmp, 0);
m_trackerType = tmp < 0 ? TrackerFLL : tmp > 1 ? TrackerPLL : (TrackerType) tmp;
d.readU32(13, &utmp, 1);
m_pllPskOrder = utmp > 4 ? 4 : utmp;
d.readBool(14, &m_rrc, false);
d.readU32(15, &utmp, 35);
m_rrcRolloff = utmp > 100 ? 100 : utmp;
d.readBool(16, &m_useReverseAPI, false);
d.readString(17, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(18, &utmp, 0);
if ((utmp > 1023) && (utmp < 65535)) {
m_reverseAPIPort = utmp;
} else {
m_reverseAPIPort = 8888;
}
d.readU32(19, &utmp, 0);
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
d.readU32(20, &utmp, 0);
m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
return true;
}
else
{
resetToDefaults();
return false;
}
}

View File

@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
// //
// This program 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 as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program 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 V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_CHANNELRX_FREQTRACKER_FREQTRACKERSETTINGS_H_
#define PLUGINS_CHANNELRX_FREQTRACKER_FREQTRACKERSETTINGS_H_
#include <QByteArray>
#include <QString>
#include "dsp/dsptypes.h"
class Serializable;
struct FreqTrackerSettings
{
enum TrackerType
{
TrackerFLL,
TrackerPLL
};
qint32 m_inputFrequencyOffset;
Real m_rfBandwidth;
uint32_t m_log2Decim;
Real m_squelch;
quint32 m_rgbColor;
QString m_title;
Serializable *m_channelMarker;
bool m_tracking;
TrackerType m_trackerType;
uint32_t m_pllPskOrder;
bool m_rrc;
uint32_t m_rrcRolloff; //!< in 100ths
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex;
uint16_t m_reverseAPIChannelIndex;
FreqTrackerSettings();
void resetToDefaults();
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
};
#endif /* PLUGINS_CHANNELRX_FREQTRACKER_FREQTRACKERSETTINGS_H_ */

View File

@ -0,0 +1,55 @@
<h1>AM demodulator plugin</h1>
<h2>Introduction</h2>
This plugin can be used to listen to a narrowband amplitude modulated signal. "Narrowband" means that the bandwidth can vary from 1 to 40 kHz.
<h2>Interface</h2>
![AM Demodulator plugin GUI](../../../doc/img/AMDemod_plugin.png)
<h3>1: Frequency shift from center frequency of reception</h3>
Use the wheels to adjust the frequency shift in Hz from the center frequency of reception. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2.
<h3>2: PLL and synchronous AM</h2>
Use this toggle button to turn on or off the PLL locking and synchronous AM detection. When on the input signal is mixed with the NCO of the PLL that locks to the carrier of the AM transmission. Then the signal is processed as a DSB or SSB (see control 3) modulated signal. The main advantage compared to enveloppe detection is a better resilience to carrier selective fading. This does not prevents all selective fading distorsion but addresses the most annoying.
When the PLL is locked the icon lights up in green. The frequency shift from carrier appears in the tooltip. Locking indicator is pretty sharp with about +/- 100 Hz range.
<h3>3: DSB/SSB selection</h2>
Use the left mouse button to toggle DSB/SSB operation. Soemtimes one of the two sidebands is affected by interference. Selecting SSB may help by using only the sideband without interference. Right click to open a dialog to select which sideband is used (LSB or USB).
<h3>4: Channel power</h3>
Average total power in dB relative to a +/- 1.0 amplitude signal received in the pass band.
<h3>5: Audio mute and audio output select</h3>
Left click on this button to toggle audio mute for this channel. The button will light up in green if the squelch is open. This helps identifying which channels are active in a multi-channel configuration.
If you right click on it it will open a dialog to select the audio output device. See [audio management documentation](../../../sdrgui/audio.md) for details.
<h3>6: Level meter in dB</h3>
- top bar (green): average value
- bottom bar (blue green): instantaneous peak value
- tip vertical bar (bright green): peak hold value
<h3>7:Bandpass boxcar filter toggle</h3>
Use this button to enable or disable the bandpass boxcar (sharp) filter with low cutoff at 300 Hz and high cutoff at half the RF bandwidth. This may help readability of low signals on air traffic communications but degrades audio on comfortable AM broadcast transmissions.
<h3>8: RF bandwidth</h3>
This is the bandwidth in kHz of the channel signal before demodulation. It can be set continuously in 1 kHz steps from 1 to 40 kHz.
<h3>9: Volume</h3>
This is the volume of the audio signal from 0.0 (mute) to 10.0 (maximum). It can be varied continuously in 0.1 steps using the dial button.
<h3>10: Squelch threshold</h3>
This is the squelch threshold in dB. The average total power received in the signal bandwidth before demodulation is compared to this value and the squelch input is open above this value. It can be varied continuously in 0.1 dB steps from 0.0 to -100.0 dB using the dial button.

View File

@ -125,7 +125,6 @@ void LocalSink::stop()
bool LocalSink::handleMessage(const Message& cmd) bool LocalSink::handleMessage(const Message& cmd)
{ {
(void) cmd;
if (DownChannelizer::MsgChannelizerNotification::match(cmd)) if (DownChannelizer::MsgChannelizerNotification::match(cmd))
{ {
DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd; DownChannelizer::MsgChannelizerNotification& notif = (DownChannelizer::MsgChannelizerNotification&) cmd;

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>320</width> <width>320</width>
<height>100</height> <height>110</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -37,13 +37,16 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Local sink</string> <string>Local sink</string>
</property> </property>
<property name="statusTip">
<string>Local Sink</string>
</property>
<widget class="QWidget" name="settingsContainer" native="true"> <widget class="QWidget" name="settingsContainer" native="true">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>10</y> <y>10</y>
<width>301</width> <width>301</width>
<height>141</height> <height>91</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -310,23 +313,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>

View File

@ -1764,6 +1764,9 @@ margin-bottom: 20px;
"FreeDVModReport" : { "FreeDVModReport" : {
"$ref" : "#/definitions/FreeDVModReport" "$ref" : "#/definitions/FreeDVModReport"
}, },
"FreqTrackerReport" : {
"$ref" : "#/definitions/FreqTrackerReport"
},
"NFMDemodReport" : { "NFMDemodReport" : {
"$ref" : "#/definitions/NFMDemodReport" "$ref" : "#/definitions/NFMDemodReport"
}, },
@ -1835,6 +1838,9 @@ margin-bottom: 20px;
"FreeDVModSettings" : { "FreeDVModSettings" : {
"$ref" : "#/definitions/FreeDVModSettings" "$ref" : "#/definitions/FreeDVModSettings"
}, },
"FreqTrackerSettings" : {
"$ref" : "#/definitions/FreqTrackerSettings"
},
"NFMDemodSettings" : { "NFMDemodSettings" : {
"$ref" : "#/definitions/NFMDemodSettings" "$ref" : "#/definitions/NFMDemodSettings"
}, },
@ -2729,6 +2735,91 @@ margin-bottom: 20px;
} }
}, },
"description" : "FreeDVMod" "description" : "FreeDVMod"
};
defs.FreqTrackerReport = {
"properties" : {
"channelPowerDB" : {
"type" : "number",
"format" : "float",
"description" : "power received in channel (dB)"
},
"squelch" : {
"type" : "integer",
"description" : "squelch status (1 if open else 0)"
},
"sampleRate" : {
"type" : "integer"
},
"channelSampleRate" : {
"type" : "integer"
}
},
"description" : "FreqTracker"
};
defs.FreqTrackerSettings = {
"properties" : {
"inputFrequencyOffset" : {
"type" : "integer",
"format" : "int64",
"description" : "channel center frequency shift from baseband center in Hz"
},
"rfBandwidth" : {
"type" : "number",
"format" : "float",
"description" : "channel RF bandwidth in Hz (floors to next 100 Hz)"
},
"log2Decim" : {
"type" : "integer"
},
"squelch" : {
"type" : "number",
"format" : "float",
"description" : "power squelch threshold in decibels"
},
"rgbColor" : {
"type" : "integer"
},
"title" : {
"type" : "string"
},
"tracking" : {
"type" : "integer",
"description" : "Tracking 1 for enabled 0 for disabled"
},
"trackerType" : {
"type" : "integer",
"description" : "Tracker element type (FLL, PLL...)"
},
"pllPskOrder" : {
"type" : "integer",
"description" : "M-ary PSK type (log2)"
},
"rrc" : {
"type" : "integer",
"description" : "RRC filter (1 for on, 0 for off)"
},
"rrcRolloff" : {
"type" : "integer",
"description" : "RRC filter rolloff factor in %"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
},
"reverseAPIChannelIndex" : {
"type" : "integer"
}
},
"description" : "FreqTracker"
}; };
defs.Frequency = { defs.Frequency = {
"properties" : { "properties" : {
@ -24824,7 +24915,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2019-05-01T23:54:36.944+02:00 Generated 2019-05-03T21:05:56.826+02:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,62 @@
FreqTrackerSettings:
description: FreqTracker
properties:
inputFrequencyOffset:
description: channel center frequency shift from baseband center in Hz
type: integer
format: int64
rfBandwidth:
description: channel RF bandwidth in Hz (floors to next 100 Hz)
type: number
format: float
log2Decim:
type: integer
squelch:
description: power squelch threshold in decibels
type: number
format: float
rgbColor:
type: integer
title:
type: string
tracking:
description: Tracking 1 for enabled 0 for disabled
type: integer
trackerType:
description: Tracker element type (FLL, PLL...)
type: integer
pllPskOrder:
description: M-ary PSK type (log2)
type: integer
rrc:
description: RRC filter (1 for on, 0 for off)
type: integer
rrcRolloff:
description: RRC filter rolloff factor in %
type: integer
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer
reverseAPIChannelIndex:
type: integer
FreqTrackerReport:
description: FreqTracker
properties:
channelPowerDB:
description: power received in channel (dB)
type: number
format: float
squelch:
description: squelch status (1 if open else 0)
type: integer
sampleRate:
type: integer
channelSampleRate:
type: integer

View File

@ -1919,6 +1919,8 @@ definitions:
$ref: "/doc/swagger/include/FreeDVDemod.yaml#/FreeDVDemodSettings" $ref: "/doc/swagger/include/FreeDVDemod.yaml#/FreeDVDemodSettings"
FreeDVModSettings: FreeDVModSettings:
$ref: "/doc/swagger/include/FreeDVMod.yaml#/FreeDVModSettings" $ref: "/doc/swagger/include/FreeDVMod.yaml#/FreeDVModSettings"
FreqTrackerSettings:
$ref: "/doc/swagger/include/FreqTracker.yaml#/FreqTrackerSettings"
NFMDemodSettings: NFMDemodSettings:
$ref: "/doc/swagger/include/NFMDemod.yaml#/NFMDemodSettings" $ref: "/doc/swagger/include/NFMDemod.yaml#/NFMDemodSettings"
NFMModSettings: NFMModSettings:
@ -1966,6 +1968,8 @@ definitions:
$ref: "/doc/swagger/include/FreeDVDemod.yaml#/FreeDVDemodReport" $ref: "/doc/swagger/include/FreeDVDemod.yaml#/FreeDVDemodReport"
FreeDVModReport: FreeDVModReport:
$ref: "/doc/swagger/include/FreeDVMod.yaml#/FreeDVModReport" $ref: "/doc/swagger/include/FreeDVMod.yaml#/FreeDVModReport"
FreqTrackerReport:
$ref: "/doc/swagger/include/FreqTracker.yaml#/FreqTrackerReport"
NFMDemodReport: NFMDemodReport:
$ref: "/doc/swagger/include/NFMDemod.yaml#/NFMDemodReport" $ref: "/doc/swagger/include/NFMDemod.yaml#/NFMDemodReport"
NFMModReport: NFMModReport:

View File

@ -0,0 +1,62 @@
FreqTrackerSettings:
description: FreqTracker
properties:
inputFrequencyOffset:
description: channel center frequency shift from baseband center in Hz
type: integer
format: int64
rfBandwidth:
description: channel RF bandwidth in Hz (floors to next 100 Hz)
type: number
format: float
log2Decim:
type: integer
squelch:
description: power squelch threshold in decibels
type: number
format: float
rgbColor:
type: integer
title:
type: string
tracking:
description: Tracking 1 for enabled 0 for disabled
type: integer
trackerType:
description: Tracker element type (FLL, PLL...)
type: integer
pllPskOrder:
description: M-ary PSK type (log2)
type: integer
rrc:
description: RRC filter (1 for on, 0 for off)
type: integer
rrcRolloff:
description: RRC filter rolloff factor in %
type: integer
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer
reverseAPIChannelIndex:
type: integer
FreqTrackerReport:
description: FreqTracker
properties:
channelPowerDB:
description: power received in channel (dB)
type: number
format: float
squelch:
description: squelch status (1 if open else 0)
type: integer
sampleRate:
type: integer
channelSampleRate:
type: integer

View File

@ -1919,6 +1919,8 @@ definitions:
$ref: "http://localhost:8081/api/swagger/include/FreeDVDemod.yaml#/FreeDVDemodSettings" $ref: "http://localhost:8081/api/swagger/include/FreeDVDemod.yaml#/FreeDVDemodSettings"
FreeDVModSettings: FreeDVModSettings:
$ref: "http://localhost:8081/api/swagger/include/FreeDVMod.yaml#/FreeDVModSettings" $ref: "http://localhost:8081/api/swagger/include/FreeDVMod.yaml#/FreeDVModSettings"
FreqTrackerSettings:
$ref: "http://localhost:8081/api/swagger/include/FreqTracker.yaml#/FreqTrackerSettings"
NFMDemodSettings: NFMDemodSettings:
$ref: "http://localhost:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodSettings" $ref: "http://localhost:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodSettings"
NFMModSettings: NFMModSettings:
@ -1966,6 +1968,8 @@ definitions:
$ref: "http://localhost:8081/api/swagger/include/FreeDVDemod.yaml#/FreeDVDemodReport" $ref: "http://localhost:8081/api/swagger/include/FreeDVDemod.yaml#/FreeDVDemodReport"
FreeDVModReport: FreeDVModReport:
$ref: "http://localhost:8081/api/swagger/include/FreeDVMod.yaml#/FreeDVModReport" $ref: "http://localhost:8081/api/swagger/include/FreeDVMod.yaml#/FreeDVModReport"
FreqTrackerReport:
$ref: "http://localhost:8081/api/swagger/include/FreqTracker.yaml#/FreqTrackerReport"
NFMDemodReport: NFMDemodReport:
$ref: "http://localhost:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodReport" $ref: "http://localhost:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodReport"
NFMModReport: NFMModReport:

View File

@ -1764,6 +1764,9 @@ margin-bottom: 20px;
"FreeDVModReport" : { "FreeDVModReport" : {
"$ref" : "#/definitions/FreeDVModReport" "$ref" : "#/definitions/FreeDVModReport"
}, },
"FreqTrackerReport" : {
"$ref" : "#/definitions/FreqTrackerReport"
},
"NFMDemodReport" : { "NFMDemodReport" : {
"$ref" : "#/definitions/NFMDemodReport" "$ref" : "#/definitions/NFMDemodReport"
}, },
@ -1835,6 +1838,9 @@ margin-bottom: 20px;
"FreeDVModSettings" : { "FreeDVModSettings" : {
"$ref" : "#/definitions/FreeDVModSettings" "$ref" : "#/definitions/FreeDVModSettings"
}, },
"FreqTrackerSettings" : {
"$ref" : "#/definitions/FreqTrackerSettings"
},
"NFMDemodSettings" : { "NFMDemodSettings" : {
"$ref" : "#/definitions/NFMDemodSettings" "$ref" : "#/definitions/NFMDemodSettings"
}, },
@ -2729,6 +2735,91 @@ margin-bottom: 20px;
} }
}, },
"description" : "FreeDVMod" "description" : "FreeDVMod"
};
defs.FreqTrackerReport = {
"properties" : {
"channelPowerDB" : {
"type" : "number",
"format" : "float",
"description" : "power received in channel (dB)"
},
"squelch" : {
"type" : "integer",
"description" : "squelch status (1 if open else 0)"
},
"sampleRate" : {
"type" : "integer"
},
"channelSampleRate" : {
"type" : "integer"
}
},
"description" : "FreqTracker"
};
defs.FreqTrackerSettings = {
"properties" : {
"inputFrequencyOffset" : {
"type" : "integer",
"format" : "int64",
"description" : "channel center frequency shift from baseband center in Hz"
},
"rfBandwidth" : {
"type" : "number",
"format" : "float",
"description" : "channel RF bandwidth in Hz (floors to next 100 Hz)"
},
"log2Decim" : {
"type" : "integer"
},
"squelch" : {
"type" : "number",
"format" : "float",
"description" : "power squelch threshold in decibels"
},
"rgbColor" : {
"type" : "integer"
},
"title" : {
"type" : "string"
},
"tracking" : {
"type" : "integer",
"description" : "Tracking 1 for enabled 0 for disabled"
},
"trackerType" : {
"type" : "integer",
"description" : "Tracker element type (FLL, PLL...)"
},
"pllPskOrder" : {
"type" : "integer",
"description" : "M-ary PSK type (log2)"
},
"rrc" : {
"type" : "integer",
"description" : "RRC filter (1 for on, 0 for off)"
},
"rrcRolloff" : {
"type" : "integer",
"description" : "RRC filter rolloff factor in %"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
},
"reverseAPIChannelIndex" : {
"type" : "integer"
}
},
"description" : "FreqTracker"
}; };
defs.Frequency = { defs.Frequency = {
"properties" : { "properties" : {
@ -24824,7 +24915,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2019-05-01T23:54:36.944+02:00 Generated 2019-05-03T21:05:56.826+02:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -46,6 +46,8 @@ SWGChannelReport::SWGChannelReport() {
m_free_dv_demod_report_isSet = false; m_free_dv_demod_report_isSet = false;
free_dv_mod_report = nullptr; free_dv_mod_report = nullptr;
m_free_dv_mod_report_isSet = false; m_free_dv_mod_report_isSet = false;
freq_tracker_report = nullptr;
m_freq_tracker_report_isSet = false;
nfm_demod_report = nullptr; nfm_demod_report = nullptr;
m_nfm_demod_report_isSet = false; m_nfm_demod_report_isSet = false;
nfm_mod_report = nullptr; nfm_mod_report = nullptr;
@ -90,6 +92,8 @@ SWGChannelReport::init() {
m_free_dv_demod_report_isSet = false; m_free_dv_demod_report_isSet = false;
free_dv_mod_report = new SWGFreeDVModReport(); free_dv_mod_report = new SWGFreeDVModReport();
m_free_dv_mod_report_isSet = false; m_free_dv_mod_report_isSet = false;
freq_tracker_report = new SWGFreqTrackerReport();
m_freq_tracker_report_isSet = false;
nfm_demod_report = new SWGNFMDemodReport(); nfm_demod_report = new SWGNFMDemodReport();
m_nfm_demod_report_isSet = false; m_nfm_demod_report_isSet = false;
nfm_mod_report = new SWGNFMModReport(); nfm_mod_report = new SWGNFMModReport();
@ -137,6 +141,9 @@ SWGChannelReport::cleanup() {
if(free_dv_mod_report != nullptr) { if(free_dv_mod_report != nullptr) {
delete free_dv_mod_report; delete free_dv_mod_report;
} }
if(freq_tracker_report != nullptr) {
delete freq_tracker_report;
}
if(nfm_demod_report != nullptr) { if(nfm_demod_report != nullptr) {
delete nfm_demod_report; delete nfm_demod_report;
} }
@ -195,6 +202,8 @@ SWGChannelReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&free_dv_mod_report, pJson["FreeDVModReport"], "SWGFreeDVModReport", "SWGFreeDVModReport"); ::SWGSDRangel::setValue(&free_dv_mod_report, pJson["FreeDVModReport"], "SWGFreeDVModReport", "SWGFreeDVModReport");
::SWGSDRangel::setValue(&freq_tracker_report, pJson["FreqTrackerReport"], "SWGFreqTrackerReport", "SWGFreqTrackerReport");
::SWGSDRangel::setValue(&nfm_demod_report, pJson["NFMDemodReport"], "SWGNFMDemodReport", "SWGNFMDemodReport"); ::SWGSDRangel::setValue(&nfm_demod_report, pJson["NFMDemodReport"], "SWGNFMDemodReport", "SWGNFMDemodReport");
::SWGSDRangel::setValue(&nfm_mod_report, pJson["NFMModReport"], "SWGNFMModReport", "SWGNFMModReport"); ::SWGSDRangel::setValue(&nfm_mod_report, pJson["NFMModReport"], "SWGNFMModReport", "SWGNFMModReport");
@ -256,6 +265,9 @@ SWGChannelReport::asJsonObject() {
if((free_dv_mod_report != nullptr) && (free_dv_mod_report->isSet())){ if((free_dv_mod_report != nullptr) && (free_dv_mod_report->isSet())){
toJsonValue(QString("FreeDVModReport"), free_dv_mod_report, obj, QString("SWGFreeDVModReport")); toJsonValue(QString("FreeDVModReport"), free_dv_mod_report, obj, QString("SWGFreeDVModReport"));
} }
if((freq_tracker_report != nullptr) && (freq_tracker_report->isSet())){
toJsonValue(QString("FreqTrackerReport"), freq_tracker_report, obj, QString("SWGFreqTrackerReport"));
}
if((nfm_demod_report != nullptr) && (nfm_demod_report->isSet())){ if((nfm_demod_report != nullptr) && (nfm_demod_report->isSet())){
toJsonValue(QString("NFMDemodReport"), nfm_demod_report, obj, QString("SWGNFMDemodReport")); toJsonValue(QString("NFMDemodReport"), nfm_demod_report, obj, QString("SWGNFMDemodReport"));
} }
@ -377,6 +389,16 @@ SWGChannelReport::setFreeDvModReport(SWGFreeDVModReport* free_dv_mod_report) {
this->m_free_dv_mod_report_isSet = true; this->m_free_dv_mod_report_isSet = true;
} }
SWGFreqTrackerReport*
SWGChannelReport::getFreqTrackerReport() {
return freq_tracker_report;
}
void
SWGChannelReport::setFreqTrackerReport(SWGFreqTrackerReport* freq_tracker_report) {
this->freq_tracker_report = freq_tracker_report;
this->m_freq_tracker_report_isSet = true;
}
SWGNFMDemodReport* SWGNFMDemodReport*
SWGChannelReport::getNfmDemodReport() { SWGChannelReport::getNfmDemodReport() {
return nfm_demod_report; return nfm_demod_report;
@ -481,6 +503,7 @@ SWGChannelReport::isSet(){
if(dsd_demod_report != nullptr && dsd_demod_report->isSet()){ isObjectUpdated = true; break;} if(dsd_demod_report != nullptr && dsd_demod_report->isSet()){ isObjectUpdated = true; break;}
if(free_dv_demod_report != nullptr && free_dv_demod_report->isSet()){ isObjectUpdated = true; break;} if(free_dv_demod_report != nullptr && free_dv_demod_report->isSet()){ isObjectUpdated = true; break;}
if(free_dv_mod_report != nullptr && free_dv_mod_report->isSet()){ isObjectUpdated = true; break;} if(free_dv_mod_report != nullptr && free_dv_mod_report->isSet()){ isObjectUpdated = true; break;}
if(freq_tracker_report != nullptr && freq_tracker_report->isSet()){ isObjectUpdated = true; break;}
if(nfm_demod_report != nullptr && nfm_demod_report->isSet()){ isObjectUpdated = true; break;} if(nfm_demod_report != nullptr && nfm_demod_report->isSet()){ isObjectUpdated = true; break;}
if(nfm_mod_report != nullptr && nfm_mod_report->isSet()){ isObjectUpdated = true; break;} if(nfm_mod_report != nullptr && nfm_mod_report->isSet()){ isObjectUpdated = true; break;}
if(ssb_demod_report != nullptr && ssb_demod_report->isSet()){ isObjectUpdated = true; break;} if(ssb_demod_report != nullptr && ssb_demod_report->isSet()){ isObjectUpdated = true; break;}

View File

@ -29,6 +29,7 @@
#include "SWGDSDDemodReport.h" #include "SWGDSDDemodReport.h"
#include "SWGFreeDVDemodReport.h" #include "SWGFreeDVDemodReport.h"
#include "SWGFreeDVModReport.h" #include "SWGFreeDVModReport.h"
#include "SWGFreqTrackerReport.h"
#include "SWGNFMDemodReport.h" #include "SWGNFMDemodReport.h"
#include "SWGNFMModReport.h" #include "SWGNFMModReport.h"
#include "SWGRemoteSourceReport.h" #include "SWGRemoteSourceReport.h"
@ -85,6 +86,9 @@ public:
SWGFreeDVModReport* getFreeDvModReport(); SWGFreeDVModReport* getFreeDvModReport();
void setFreeDvModReport(SWGFreeDVModReport* free_dv_mod_report); void setFreeDvModReport(SWGFreeDVModReport* free_dv_mod_report);
SWGFreqTrackerReport* getFreqTrackerReport();
void setFreqTrackerReport(SWGFreqTrackerReport* freq_tracker_report);
SWGNFMDemodReport* getNfmDemodReport(); SWGNFMDemodReport* getNfmDemodReport();
void setNfmDemodReport(SWGNFMDemodReport* nfm_demod_report); void setNfmDemodReport(SWGNFMDemodReport* nfm_demod_report);
@ -143,6 +147,9 @@ private:
SWGFreeDVModReport* free_dv_mod_report; SWGFreeDVModReport* free_dv_mod_report;
bool m_free_dv_mod_report_isSet; bool m_free_dv_mod_report_isSet;
SWGFreqTrackerReport* freq_tracker_report;
bool m_freq_tracker_report_isSet;
SWGNFMDemodReport* nfm_demod_report; SWGNFMDemodReport* nfm_demod_report;
bool m_nfm_demod_report_isSet; bool m_nfm_demod_report_isSet;

View File

@ -50,6 +50,8 @@ SWGChannelSettings::SWGChannelSettings() {
m_free_dv_demod_settings_isSet = false; m_free_dv_demod_settings_isSet = false;
free_dv_mod_settings = nullptr; free_dv_mod_settings = nullptr;
m_free_dv_mod_settings_isSet = false; m_free_dv_mod_settings_isSet = false;
freq_tracker_settings = nullptr;
m_freq_tracker_settings_isSet = false;
nfm_demod_settings = nullptr; nfm_demod_settings = nullptr;
m_nfm_demod_settings_isSet = false; m_nfm_demod_settings_isSet = false;
nfm_mod_settings = nullptr; nfm_mod_settings = nullptr;
@ -102,6 +104,8 @@ SWGChannelSettings::init() {
m_free_dv_demod_settings_isSet = false; m_free_dv_demod_settings_isSet = false;
free_dv_mod_settings = new SWGFreeDVModSettings(); free_dv_mod_settings = new SWGFreeDVModSettings();
m_free_dv_mod_settings_isSet = false; m_free_dv_mod_settings_isSet = false;
freq_tracker_settings = new SWGFreqTrackerSettings();
m_freq_tracker_settings_isSet = false;
nfm_demod_settings = new SWGNFMDemodSettings(); nfm_demod_settings = new SWGNFMDemodSettings();
m_nfm_demod_settings_isSet = false; m_nfm_demod_settings_isSet = false;
nfm_mod_settings = new SWGNFMModSettings(); nfm_mod_settings = new SWGNFMModSettings();
@ -155,6 +159,9 @@ SWGChannelSettings::cleanup() {
if(free_dv_mod_settings != nullptr) { if(free_dv_mod_settings != nullptr) {
delete free_dv_mod_settings; delete free_dv_mod_settings;
} }
if(freq_tracker_settings != nullptr) {
delete freq_tracker_settings;
}
if(nfm_demod_settings != nullptr) { if(nfm_demod_settings != nullptr) {
delete nfm_demod_settings; delete nfm_demod_settings;
} }
@ -223,6 +230,8 @@ SWGChannelSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&free_dv_mod_settings, pJson["FreeDVModSettings"], "SWGFreeDVModSettings", "SWGFreeDVModSettings"); ::SWGSDRangel::setValue(&free_dv_mod_settings, pJson["FreeDVModSettings"], "SWGFreeDVModSettings", "SWGFreeDVModSettings");
::SWGSDRangel::setValue(&freq_tracker_settings, pJson["FreqTrackerSettings"], "SWGFreqTrackerSettings", "SWGFreqTrackerSettings");
::SWGSDRangel::setValue(&nfm_demod_settings, pJson["NFMDemodSettings"], "SWGNFMDemodSettings", "SWGNFMDemodSettings"); ::SWGSDRangel::setValue(&nfm_demod_settings, pJson["NFMDemodSettings"], "SWGNFMDemodSettings", "SWGNFMDemodSettings");
::SWGSDRangel::setValue(&nfm_mod_settings, pJson["NFMModSettings"], "SWGNFMModSettings", "SWGNFMModSettings"); ::SWGSDRangel::setValue(&nfm_mod_settings, pJson["NFMModSettings"], "SWGNFMModSettings", "SWGNFMModSettings");
@ -294,6 +303,9 @@ SWGChannelSettings::asJsonObject() {
if((free_dv_mod_settings != nullptr) && (free_dv_mod_settings->isSet())){ if((free_dv_mod_settings != nullptr) && (free_dv_mod_settings->isSet())){
toJsonValue(QString("FreeDVModSettings"), free_dv_mod_settings, obj, QString("SWGFreeDVModSettings")); toJsonValue(QString("FreeDVModSettings"), free_dv_mod_settings, obj, QString("SWGFreeDVModSettings"));
} }
if((freq_tracker_settings != nullptr) && (freq_tracker_settings->isSet())){
toJsonValue(QString("FreqTrackerSettings"), freq_tracker_settings, obj, QString("SWGFreqTrackerSettings"));
}
if((nfm_demod_settings != nullptr) && (nfm_demod_settings->isSet())){ if((nfm_demod_settings != nullptr) && (nfm_demod_settings->isSet())){
toJsonValue(QString("NFMDemodSettings"), nfm_demod_settings, obj, QString("SWGNFMDemodSettings")); toJsonValue(QString("NFMDemodSettings"), nfm_demod_settings, obj, QString("SWGNFMDemodSettings"));
} }
@ -441,6 +453,16 @@ SWGChannelSettings::setFreeDvModSettings(SWGFreeDVModSettings* free_dv_mod_setti
this->m_free_dv_mod_settings_isSet = true; this->m_free_dv_mod_settings_isSet = true;
} }
SWGFreqTrackerSettings*
SWGChannelSettings::getFreqTrackerSettings() {
return freq_tracker_settings;
}
void
SWGChannelSettings::setFreqTrackerSettings(SWGFreqTrackerSettings* freq_tracker_settings) {
this->freq_tracker_settings = freq_tracker_settings;
this->m_freq_tracker_settings_isSet = true;
}
SWGNFMDemodSettings* SWGNFMDemodSettings*
SWGChannelSettings::getNfmDemodSettings() { SWGChannelSettings::getNfmDemodSettings() {
return nfm_demod_settings; return nfm_demod_settings;
@ -567,6 +589,7 @@ SWGChannelSettings::isSet(){
if(dsd_demod_settings != nullptr && dsd_demod_settings->isSet()){ isObjectUpdated = true; break;} if(dsd_demod_settings != nullptr && dsd_demod_settings->isSet()){ isObjectUpdated = true; break;}
if(free_dv_demod_settings != nullptr && free_dv_demod_settings->isSet()){ isObjectUpdated = true; break;} if(free_dv_demod_settings != nullptr && free_dv_demod_settings->isSet()){ isObjectUpdated = true; break;}
if(free_dv_mod_settings != nullptr && free_dv_mod_settings->isSet()){ isObjectUpdated = true; break;} if(free_dv_mod_settings != nullptr && free_dv_mod_settings->isSet()){ isObjectUpdated = true; break;}
if(freq_tracker_settings != nullptr && freq_tracker_settings->isSet()){ isObjectUpdated = true; break;}
if(nfm_demod_settings != nullptr && nfm_demod_settings->isSet()){ isObjectUpdated = true; break;} if(nfm_demod_settings != nullptr && nfm_demod_settings->isSet()){ isObjectUpdated = true; break;}
if(nfm_mod_settings != nullptr && nfm_mod_settings->isSet()){ isObjectUpdated = true; break;} if(nfm_mod_settings != nullptr && nfm_mod_settings->isSet()){ isObjectUpdated = true; break;}
if(local_sink_settings != nullptr && local_sink_settings->isSet()){ isObjectUpdated = true; break;} if(local_sink_settings != nullptr && local_sink_settings->isSet()){ isObjectUpdated = true; break;}

View File

@ -29,6 +29,7 @@
#include "SWGDSDDemodSettings.h" #include "SWGDSDDemodSettings.h"
#include "SWGFreeDVDemodSettings.h" #include "SWGFreeDVDemodSettings.h"
#include "SWGFreeDVModSettings.h" #include "SWGFreeDVModSettings.h"
#include "SWGFreqTrackerSettings.h"
#include "SWGLocalSinkSettings.h" #include "SWGLocalSinkSettings.h"
#include "SWGNFMDemodSettings.h" #include "SWGNFMDemodSettings.h"
#include "SWGNFMModSettings.h" #include "SWGNFMModSettings.h"
@ -93,6 +94,9 @@ public:
SWGFreeDVModSettings* getFreeDvModSettings(); SWGFreeDVModSettings* getFreeDvModSettings();
void setFreeDvModSettings(SWGFreeDVModSettings* free_dv_mod_settings); void setFreeDvModSettings(SWGFreeDVModSettings* free_dv_mod_settings);
SWGFreqTrackerSettings* getFreqTrackerSettings();
void setFreqTrackerSettings(SWGFreqTrackerSettings* freq_tracker_settings);
SWGNFMDemodSettings* getNfmDemodSettings(); SWGNFMDemodSettings* getNfmDemodSettings();
void setNfmDemodSettings(SWGNFMDemodSettings* nfm_demod_settings); void setNfmDemodSettings(SWGNFMDemodSettings* nfm_demod_settings);
@ -163,6 +167,9 @@ private:
SWGFreeDVModSettings* free_dv_mod_settings; SWGFreeDVModSettings* free_dv_mod_settings;
bool m_free_dv_mod_settings_isSet; bool m_free_dv_mod_settings_isSet;
SWGFreqTrackerSettings* freq_tracker_settings;
bool m_freq_tracker_settings_isSet;
SWGNFMDemodSettings* nfm_demod_settings; SWGNFMDemodSettings* nfm_demod_settings;
bool m_nfm_demod_settings_isSet; bool m_nfm_demod_settings_isSet;

View File

@ -0,0 +1,169 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.6.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
#include "SWGFreqTrackerReport.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGFreqTrackerReport::SWGFreqTrackerReport(QString* json) {
init();
this->fromJson(*json);
}
SWGFreqTrackerReport::SWGFreqTrackerReport() {
channel_power_db = 0.0f;
m_channel_power_db_isSet = false;
squelch = 0;
m_squelch_isSet = false;
sample_rate = 0;
m_sample_rate_isSet = false;
channel_sample_rate = 0;
m_channel_sample_rate_isSet = false;
}
SWGFreqTrackerReport::~SWGFreqTrackerReport() {
this->cleanup();
}
void
SWGFreqTrackerReport::init() {
channel_power_db = 0.0f;
m_channel_power_db_isSet = false;
squelch = 0;
m_squelch_isSet = false;
sample_rate = 0;
m_sample_rate_isSet = false;
channel_sample_rate = 0;
m_channel_sample_rate_isSet = false;
}
void
SWGFreqTrackerReport::cleanup() {
}
SWGFreqTrackerReport*
SWGFreqTrackerReport::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGFreqTrackerReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&channel_power_db, pJson["channelPowerDB"], "float", "");
::SWGSDRangel::setValue(&squelch, pJson["squelch"], "qint32", "");
::SWGSDRangel::setValue(&sample_rate, pJson["sampleRate"], "qint32", "");
::SWGSDRangel::setValue(&channel_sample_rate, pJson["channelSampleRate"], "qint32", "");
}
QString
SWGFreqTrackerReport::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGFreqTrackerReport::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_channel_power_db_isSet){
obj->insert("channelPowerDB", QJsonValue(channel_power_db));
}
if(m_squelch_isSet){
obj->insert("squelch", QJsonValue(squelch));
}
if(m_sample_rate_isSet){
obj->insert("sampleRate", QJsonValue(sample_rate));
}
if(m_channel_sample_rate_isSet){
obj->insert("channelSampleRate", QJsonValue(channel_sample_rate));
}
return obj;
}
float
SWGFreqTrackerReport::getChannelPowerDb() {
return channel_power_db;
}
void
SWGFreqTrackerReport::setChannelPowerDb(float channel_power_db) {
this->channel_power_db = channel_power_db;
this->m_channel_power_db_isSet = true;
}
qint32
SWGFreqTrackerReport::getSquelch() {
return squelch;
}
void
SWGFreqTrackerReport::setSquelch(qint32 squelch) {
this->squelch = squelch;
this->m_squelch_isSet = true;
}
qint32
SWGFreqTrackerReport::getSampleRate() {
return sample_rate;
}
void
SWGFreqTrackerReport::setSampleRate(qint32 sample_rate) {
this->sample_rate = sample_rate;
this->m_sample_rate_isSet = true;
}
qint32
SWGFreqTrackerReport::getChannelSampleRate() {
return channel_sample_rate;
}
void
SWGFreqTrackerReport::setChannelSampleRate(qint32 channel_sample_rate) {
this->channel_sample_rate = channel_sample_rate;
this->m_channel_sample_rate_isSet = true;
}
bool
SWGFreqTrackerReport::isSet(){
bool isObjectUpdated = false;
do{
if(m_channel_power_db_isSet){ isObjectUpdated = true; break;}
if(m_squelch_isSet){ isObjectUpdated = true; break;}
if(m_sample_rate_isSet){ isObjectUpdated = true; break;}
if(m_channel_sample_rate_isSet){ isObjectUpdated = true; break;}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,76 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.6.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/*
* SWGFreqTrackerReport.h
*
* FreqTracker
*/
#ifndef SWGFreqTrackerReport_H_
#define SWGFreqTrackerReport_H_
#include <QJsonObject>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGFreqTrackerReport: public SWGObject {
public:
SWGFreqTrackerReport();
SWGFreqTrackerReport(QString* json);
virtual ~SWGFreqTrackerReport();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGFreqTrackerReport* fromJson(QString &jsonString) override;
float getChannelPowerDb();
void setChannelPowerDb(float channel_power_db);
qint32 getSquelch();
void setSquelch(qint32 squelch);
qint32 getSampleRate();
void setSampleRate(qint32 sample_rate);
qint32 getChannelSampleRate();
void setChannelSampleRate(qint32 channel_sample_rate);
virtual bool isSet() override;
private:
float channel_power_db;
bool m_channel_power_db_isSet;
qint32 squelch;
bool m_squelch_isSet;
qint32 sample_rate;
bool m_sample_rate_isSet;
qint32 channel_sample_rate;
bool m_channel_sample_rate_isSet;
};
}
#endif /* SWGFreqTrackerReport_H_ */

View File

@ -0,0 +1,425 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.6.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
#include "SWGFreqTrackerSettings.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGFreqTrackerSettings::SWGFreqTrackerSettings(QString* json) {
init();
this->fromJson(*json);
}
SWGFreqTrackerSettings::SWGFreqTrackerSettings() {
input_frequency_offset = 0L;
m_input_frequency_offset_isSet = false;
rf_bandwidth = 0.0f;
m_rf_bandwidth_isSet = false;
log2_decim = 0;
m_log2_decim_isSet = false;
squelch = 0.0f;
m_squelch_isSet = false;
rgb_color = 0;
m_rgb_color_isSet = false;
title = nullptr;
m_title_isSet = false;
tracking = 0;
m_tracking_isSet = false;
tracker_type = 0;
m_tracker_type_isSet = false;
pll_psk_order = 0;
m_pll_psk_order_isSet = false;
rrc = 0;
m_rrc_isSet = false;
rrc_rolloff = 0;
m_rrc_rolloff_isSet = false;
use_reverse_api = 0;
m_use_reverse_api_isSet = false;
reverse_api_address = nullptr;
m_reverse_api_address_isSet = false;
reverse_api_port = 0;
m_reverse_api_port_isSet = false;
reverse_api_device_index = 0;
m_reverse_api_device_index_isSet = false;
reverse_api_channel_index = 0;
m_reverse_api_channel_index_isSet = false;
}
SWGFreqTrackerSettings::~SWGFreqTrackerSettings() {
this->cleanup();
}
void
SWGFreqTrackerSettings::init() {
input_frequency_offset = 0L;
m_input_frequency_offset_isSet = false;
rf_bandwidth = 0.0f;
m_rf_bandwidth_isSet = false;
log2_decim = 0;
m_log2_decim_isSet = false;
squelch = 0.0f;
m_squelch_isSet = false;
rgb_color = 0;
m_rgb_color_isSet = false;
title = new QString("");
m_title_isSet = false;
tracking = 0;
m_tracking_isSet = false;
tracker_type = 0;
m_tracker_type_isSet = false;
pll_psk_order = 0;
m_pll_psk_order_isSet = false;
rrc = 0;
m_rrc_isSet = false;
rrc_rolloff = 0;
m_rrc_rolloff_isSet = false;
use_reverse_api = 0;
m_use_reverse_api_isSet = false;
reverse_api_address = new QString("");
m_reverse_api_address_isSet = false;
reverse_api_port = 0;
m_reverse_api_port_isSet = false;
reverse_api_device_index = 0;
m_reverse_api_device_index_isSet = false;
reverse_api_channel_index = 0;
m_reverse_api_channel_index_isSet = false;
}
void
SWGFreqTrackerSettings::cleanup() {
if(title != nullptr) {
delete title;
}
if(reverse_api_address != nullptr) {
delete reverse_api_address;
}
}
SWGFreqTrackerSettings*
SWGFreqTrackerSettings::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGFreqTrackerSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "float", "");
::SWGSDRangel::setValue(&log2_decim, pJson["log2Decim"], "qint32", "");
::SWGSDRangel::setValue(&squelch, pJson["squelch"], "float", "");
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
::SWGSDRangel::setValue(&tracking, pJson["tracking"], "qint32", "");
::SWGSDRangel::setValue(&tracker_type, pJson["trackerType"], "qint32", "");
::SWGSDRangel::setValue(&pll_psk_order, pJson["pllPskOrder"], "qint32", "");
::SWGSDRangel::setValue(&rrc, pJson["rrc"], "qint32", "");
::SWGSDRangel::setValue(&rrc_rolloff, pJson["rrcRolloff"], "qint32", "");
::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", "");
::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString");
::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", "");
::SWGSDRangel::setValue(&reverse_api_device_index, pJson["reverseAPIDeviceIndex"], "qint32", "");
::SWGSDRangel::setValue(&reverse_api_channel_index, pJson["reverseAPIChannelIndex"], "qint32", "");
}
QString
SWGFreqTrackerSettings::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGFreqTrackerSettings::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_input_frequency_offset_isSet){
obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset));
}
if(m_rf_bandwidth_isSet){
obj->insert("rfBandwidth", QJsonValue(rf_bandwidth));
}
if(m_log2_decim_isSet){
obj->insert("log2Decim", QJsonValue(log2_decim));
}
if(m_squelch_isSet){
obj->insert("squelch", QJsonValue(squelch));
}
if(m_rgb_color_isSet){
obj->insert("rgbColor", QJsonValue(rgb_color));
}
if(title != nullptr && *title != QString("")){
toJsonValue(QString("title"), title, obj, QString("QString"));
}
if(m_tracking_isSet){
obj->insert("tracking", QJsonValue(tracking));
}
if(m_tracker_type_isSet){
obj->insert("trackerType", QJsonValue(tracker_type));
}
if(m_pll_psk_order_isSet){
obj->insert("pllPskOrder", QJsonValue(pll_psk_order));
}
if(m_rrc_isSet){
obj->insert("rrc", QJsonValue(rrc));
}
if(m_rrc_rolloff_isSet){
obj->insert("rrcRolloff", QJsonValue(rrc_rolloff));
}
if(m_use_reverse_api_isSet){
obj->insert("useReverseAPI", QJsonValue(use_reverse_api));
}
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){
toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString"));
}
if(m_reverse_api_port_isSet){
obj->insert("reverseAPIPort", QJsonValue(reverse_api_port));
}
if(m_reverse_api_device_index_isSet){
obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index));
}
if(m_reverse_api_channel_index_isSet){
obj->insert("reverseAPIChannelIndex", QJsonValue(reverse_api_channel_index));
}
return obj;
}
qint64
SWGFreqTrackerSettings::getInputFrequencyOffset() {
return input_frequency_offset;
}
void
SWGFreqTrackerSettings::setInputFrequencyOffset(qint64 input_frequency_offset) {
this->input_frequency_offset = input_frequency_offset;
this->m_input_frequency_offset_isSet = true;
}
float
SWGFreqTrackerSettings::getRfBandwidth() {
return rf_bandwidth;
}
void
SWGFreqTrackerSettings::setRfBandwidth(float rf_bandwidth) {
this->rf_bandwidth = rf_bandwidth;
this->m_rf_bandwidth_isSet = true;
}
qint32
SWGFreqTrackerSettings::getLog2Decim() {
return log2_decim;
}
void
SWGFreqTrackerSettings::setLog2Decim(qint32 log2_decim) {
this->log2_decim = log2_decim;
this->m_log2_decim_isSet = true;
}
float
SWGFreqTrackerSettings::getSquelch() {
return squelch;
}
void
SWGFreqTrackerSettings::setSquelch(float squelch) {
this->squelch = squelch;
this->m_squelch_isSet = true;
}
qint32
SWGFreqTrackerSettings::getRgbColor() {
return rgb_color;
}
void
SWGFreqTrackerSettings::setRgbColor(qint32 rgb_color) {
this->rgb_color = rgb_color;
this->m_rgb_color_isSet = true;
}
QString*
SWGFreqTrackerSettings::getTitle() {
return title;
}
void
SWGFreqTrackerSettings::setTitle(QString* title) {
this->title = title;
this->m_title_isSet = true;
}
qint32
SWGFreqTrackerSettings::getTracking() {
return tracking;
}
void
SWGFreqTrackerSettings::setTracking(qint32 tracking) {
this->tracking = tracking;
this->m_tracking_isSet = true;
}
qint32
SWGFreqTrackerSettings::getTrackerType() {
return tracker_type;
}
void
SWGFreqTrackerSettings::setTrackerType(qint32 tracker_type) {
this->tracker_type = tracker_type;
this->m_tracker_type_isSet = true;
}
qint32
SWGFreqTrackerSettings::getPllPskOrder() {
return pll_psk_order;
}
void
SWGFreqTrackerSettings::setPllPskOrder(qint32 pll_psk_order) {
this->pll_psk_order = pll_psk_order;
this->m_pll_psk_order_isSet = true;
}
qint32
SWGFreqTrackerSettings::getRrc() {
return rrc;
}
void
SWGFreqTrackerSettings::setRrc(qint32 rrc) {
this->rrc = rrc;
this->m_rrc_isSet = true;
}
qint32
SWGFreqTrackerSettings::getRrcRolloff() {
return rrc_rolloff;
}
void
SWGFreqTrackerSettings::setRrcRolloff(qint32 rrc_rolloff) {
this->rrc_rolloff = rrc_rolloff;
this->m_rrc_rolloff_isSet = true;
}
qint32
SWGFreqTrackerSettings::getUseReverseApi() {
return use_reverse_api;
}
void
SWGFreqTrackerSettings::setUseReverseApi(qint32 use_reverse_api) {
this->use_reverse_api = use_reverse_api;
this->m_use_reverse_api_isSet = true;
}
QString*
SWGFreqTrackerSettings::getReverseApiAddress() {
return reverse_api_address;
}
void
SWGFreqTrackerSettings::setReverseApiAddress(QString* reverse_api_address) {
this->reverse_api_address = reverse_api_address;
this->m_reverse_api_address_isSet = true;
}
qint32
SWGFreqTrackerSettings::getReverseApiPort() {
return reverse_api_port;
}
void
SWGFreqTrackerSettings::setReverseApiPort(qint32 reverse_api_port) {
this->reverse_api_port = reverse_api_port;
this->m_reverse_api_port_isSet = true;
}
qint32
SWGFreqTrackerSettings::getReverseApiDeviceIndex() {
return reverse_api_device_index;
}
void
SWGFreqTrackerSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
this->reverse_api_device_index = reverse_api_device_index;
this->m_reverse_api_device_index_isSet = true;
}
qint32
SWGFreqTrackerSettings::getReverseApiChannelIndex() {
return reverse_api_channel_index;
}
void
SWGFreqTrackerSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) {
this->reverse_api_channel_index = reverse_api_channel_index;
this->m_reverse_api_channel_index_isSet = true;
}
bool
SWGFreqTrackerSettings::isSet(){
bool isObjectUpdated = false;
do{
if(m_input_frequency_offset_isSet){ isObjectUpdated = true; break;}
if(m_rf_bandwidth_isSet){ isObjectUpdated = true; break;}
if(m_log2_decim_isSet){ isObjectUpdated = true; break;}
if(m_squelch_isSet){ isObjectUpdated = true; break;}
if(m_rgb_color_isSet){ isObjectUpdated = true; break;}
if(title != nullptr && *title != QString("")){ isObjectUpdated = true; break;}
if(m_tracking_isSet){ isObjectUpdated = true; break;}
if(m_tracker_type_isSet){ isObjectUpdated = true; break;}
if(m_pll_psk_order_isSet){ isObjectUpdated = true; break;}
if(m_rrc_isSet){ isObjectUpdated = true; break;}
if(m_rrc_rolloff_isSet){ isObjectUpdated = true; break;}
if(m_use_reverse_api_isSet){ isObjectUpdated = true; break;}
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){ isObjectUpdated = true; break;}
if(m_reverse_api_port_isSet){ isObjectUpdated = true; break;}
if(m_reverse_api_device_index_isSet){ isObjectUpdated = true; break;}
if(m_reverse_api_channel_index_isSet){ isObjectUpdated = true; break;}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,149 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.6.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/*
* SWGFreqTrackerSettings.h
*
* FreqTracker
*/
#ifndef SWGFreqTrackerSettings_H_
#define SWGFreqTrackerSettings_H_
#include <QJsonObject>
#include <QString>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGFreqTrackerSettings: public SWGObject {
public:
SWGFreqTrackerSettings();
SWGFreqTrackerSettings(QString* json);
virtual ~SWGFreqTrackerSettings();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGFreqTrackerSettings* fromJson(QString &jsonString) override;
qint64 getInputFrequencyOffset();
void setInputFrequencyOffset(qint64 input_frequency_offset);
float getRfBandwidth();
void setRfBandwidth(float rf_bandwidth);
qint32 getLog2Decim();
void setLog2Decim(qint32 log2_decim);
float getSquelch();
void setSquelch(float squelch);
qint32 getRgbColor();
void setRgbColor(qint32 rgb_color);
QString* getTitle();
void setTitle(QString* title);
qint32 getTracking();
void setTracking(qint32 tracking);
qint32 getTrackerType();
void setTrackerType(qint32 tracker_type);
qint32 getPllPskOrder();
void setPllPskOrder(qint32 pll_psk_order);
qint32 getRrc();
void setRrc(qint32 rrc);
qint32 getRrcRolloff();
void setRrcRolloff(qint32 rrc_rolloff);
qint32 getUseReverseApi();
void setUseReverseApi(qint32 use_reverse_api);
QString* getReverseApiAddress();
void setReverseApiAddress(QString* reverse_api_address);
qint32 getReverseApiPort();
void setReverseApiPort(qint32 reverse_api_port);
qint32 getReverseApiDeviceIndex();
void setReverseApiDeviceIndex(qint32 reverse_api_device_index);
qint32 getReverseApiChannelIndex();
void setReverseApiChannelIndex(qint32 reverse_api_channel_index);
virtual bool isSet() override;
private:
qint64 input_frequency_offset;
bool m_input_frequency_offset_isSet;
float rf_bandwidth;
bool m_rf_bandwidth_isSet;
qint32 log2_decim;
bool m_log2_decim_isSet;
float squelch;
bool m_squelch_isSet;
qint32 rgb_color;
bool m_rgb_color_isSet;
QString* title;
bool m_title_isSet;
qint32 tracking;
bool m_tracking_isSet;
qint32 tracker_type;
bool m_tracker_type_isSet;
qint32 pll_psk_order;
bool m_pll_psk_order_isSet;
qint32 rrc;
bool m_rrc_isSet;
qint32 rrc_rolloff;
bool m_rrc_rolloff_isSet;
qint32 use_reverse_api;
bool m_use_reverse_api_isSet;
QString* reverse_api_address;
bool m_reverse_api_address_isSet;
qint32 reverse_api_port;
bool m_reverse_api_port_isSet;
qint32 reverse_api_device_index;
bool m_reverse_api_device_index_isSet;
qint32 reverse_api_channel_index;
bool m_reverse_api_channel_index_isSet;
};
}
#endif /* SWGFreqTrackerSettings_H_ */

View File

@ -64,6 +64,8 @@
#include "SWGFreeDVDemodSettings.h" #include "SWGFreeDVDemodSettings.h"
#include "SWGFreeDVModReport.h" #include "SWGFreeDVModReport.h"
#include "SWGFreeDVModSettings.h" #include "SWGFreeDVModSettings.h"
#include "SWGFreqTrackerReport.h"
#include "SWGFreqTrackerSettings.h"
#include "SWGFrequency.h" #include "SWGFrequency.h"
#include "SWGFrequencyBand.h" #include "SWGFrequencyBand.h"
#include "SWGFrequencyRange.h" #include "SWGFrequencyRange.h"
@ -294,6 +296,12 @@ namespace SWGSDRangel {
if(QString("SWGFreeDVModSettings").compare(type) == 0) { if(QString("SWGFreeDVModSettings").compare(type) == 0) {
return new SWGFreeDVModSettings(); return new SWGFreeDVModSettings();
} }
if(QString("SWGFreqTrackerReport").compare(type) == 0) {
return new SWGFreqTrackerReport();
}
if(QString("SWGFreqTrackerSettings").compare(type) == 0) {
return new SWGFreqTrackerSettings();
}
if(QString("SWGFrequency").compare(type) == 0) { if(QString("SWGFrequency").compare(type) == 0) {
return new SWGFrequency(); return new SWGFrequency();
} }