From 9334a7f16aa46050953f29a16f6a3cd77046a3f1 Mon Sep 17 00:00:00 2001 From: srcejon Date: Fri, 5 Apr 2024 16:46:49 +0100 Subject: [PATCH] Channel Power: Add absolute frequency setting. --- .../channelpower/channelpowergui.cpp | 105 +++++++++++++++--- .../channelrx/channelpower/channelpowergui.h | 2 + .../channelrx/channelpower/channelpowergui.ui | 24 +++- .../channelpower/channelpowersettings.cpp | 26 ++++- .../channelpower/channelpowersettings.h | 7 +- 5 files changed, 144 insertions(+), 20 deletions(-) diff --git a/plugins/channelrx/channelpower/channelpowergui.cpp b/plugins/channelrx/channelpower/channelpowergui.cpp index dd83e053c..c05eba4e1 100644 --- a/plugins/channelrx/channelpower/channelpowergui.cpp +++ b/plugins/channelrx/channelpower/channelpowergui.cpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2016 Edouard Griffiths, F4EXB // -// Copyright (C) 2023 Jon Beniston, M7RCE // +// Copyright (C) 2023-2024 Jon Beniston, M7RCE // // // // 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 // @@ -18,8 +18,6 @@ #include -#include "channelpowergui.h" - #include "device/deviceuiset.h" #include "device/deviceapi.h" #include "dsp/dspengine.h" @@ -36,6 +34,7 @@ #include "maincore.h" #include "channelpower.h" +#include "channelpowergui.h" ChannelPowerGUI* ChannelPowerGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) { @@ -62,11 +61,14 @@ QByteArray ChannelPowerGUI::serialize() const bool ChannelPowerGUI::deserialize(const QByteArray& data) { - if(m_settings.deserialize(data)) { + if (m_settings.deserialize(data)) + { displaySettings(); applyAllSettings(); return true; - } else { + } + else + { resetToDefaults(); return false; } @@ -90,8 +92,7 @@ bool ChannelPowerGUI::handleMessage(const Message& message) DSPSignalNotification& notif = (DSPSignalNotification&) message; m_deviceCenterFrequency = notif.getCenterFrequency(); m_basebandSampleRate = notif.getSampleRate(); - ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2); - ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2)); + calcOffset(); ui->rfBW->setValueRange(floor(log10(m_basebandSampleRate))+1, 0, m_basebandSampleRate); updateAbsoluteCenterFrequency(); return true; @@ -115,9 +116,23 @@ void ChannelPowerGUI::handleInputMessages() void ChannelPowerGUI::channelMarkerChangedByCursor() { - ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency(); - applySetting("inputFrequencyOffset"); + m_settings.m_frequency = m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset; + + qint64 value = 0; + + if (m_settings.m_frequencyMode == ChannelPowerSettings::Offset) { + value = m_settings.m_inputFrequencyOffset; + } else if (m_settings.m_frequencyMode == ChannelPowerSettings::Absolute) { + value = m_settings.m_frequency; + } + + ui->deltaFrequency->blockSignals(true); + ui->deltaFrequency->setValue(value); + ui->deltaFrequency->blockSignals(false); + + updateAbsoluteCenterFrequency(); + applySettings({"frequency", "inputFrequencyOffset"}); } void ChannelPowerGUI::channelMarkerHighlightedByCursor() @@ -127,10 +142,23 @@ void ChannelPowerGUI::channelMarkerHighlightedByCursor() void ChannelPowerGUI::on_deltaFrequency_changed(qint64 value) { - m_channelMarker.setCenterFrequency(value); + qint64 offset = 0; + + if (m_settings.m_frequencyMode == ChannelPowerSettings::Offset) + { + offset = value; + m_settings.m_frequency = m_deviceCenterFrequency + offset; + } + else if (m_settings.m_frequencyMode == ChannelPowerSettings::Absolute) + { + m_settings.m_frequency = value; + offset = m_settings.m_frequency - m_deviceCenterFrequency; + } + + m_channelMarker.setCenterFrequency(offset); m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency(); updateAbsoluteCenterFrequency(); - applySetting("inputFrequencyOffset"); + applySettings({"frequency", "inputFrequencyOffset"}); } void ChannelPowerGUI::on_rfBW_changed(qint64 value) @@ -255,7 +283,6 @@ ChannelPowerGUI::ChannelPowerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, connect(&MainCore::instance()->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); @@ -334,7 +361,8 @@ void ChannelPowerGUI::displaySettings() blockApplySettings(true); - ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); + ui->frequencyMode->setCurrentIndex((int) m_settings.m_frequencyMode); + on_frequencyMode_currentIndexChanged((int) m_settings.m_frequencyMode); ui->rfBW->setValue(m_settings.m_rfBandwidth); @@ -427,6 +455,47 @@ void ChannelPowerGUI::tick() m_tickCount++; } +void ChannelPowerGUI::on_frequencyMode_currentIndexChanged(int index) +{ + m_settings.m_frequencyMode = (ChannelPowerSettings::FrequencyMode) index; + ui->deltaFrequency->blockSignals(true); + + if (m_settings.m_frequencyMode == ChannelPowerSettings::Offset) + { + ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999); + ui->deltaFrequency->setValue(m_settings.m_inputFrequencyOffset); + ui->deltaUnits->setText("Hz"); + } + else if (m_settings.m_frequencyMode == ChannelPowerSettings::Absolute) + { + ui->deltaFrequency->setValueRange(true, 11, 0, 99999999999, 0); + ui->deltaFrequency->setValue(m_settings.m_frequency); + ui->deltaUnits->setText("Hz"); + } + + ui->deltaFrequency->blockSignals(false); + + updateAbsoluteCenterFrequency(); + applySetting("frequencyMode"); +} + +// Calculate input frequency offset, when device center frequency changes +void ChannelPowerGUI::calcOffset() +{ + if (m_settings.m_frequencyMode == ChannelPowerSettings::Offset) + { + ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2); + } + else + { + qint64 offset = m_settings.m_frequency - m_deviceCenterFrequency; + m_channelMarker.setCenterFrequency(offset); + m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency(); + updateAbsoluteCenterFrequency(); + applySetting("inputFrequencyOffset"); + } +} + void ChannelPowerGUI::on_clearMeasurements_clicked() { m_channelPower->resetMagLevels(); @@ -434,6 +503,7 @@ void ChannelPowerGUI::on_clearMeasurements_clicked() void ChannelPowerGUI::makeUIConnections() { + QObject::connect(ui->frequencyMode, QOverload::of(&QComboBox::currentIndexChanged), this, &ChannelPowerGUI::on_frequencyMode_currentIndexChanged); QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &ChannelPowerGUI::on_deltaFrequency_changed); QObject::connect(ui->rfBW, &ValueDial::changed, this, &ChannelPowerGUI::on_rfBW_changed); QObject::connect(ui->pulseTH, QOverload::of(&QDial::valueChanged), this, &ChannelPowerGUI::on_pulseTH_valueChanged); @@ -443,5 +513,12 @@ void ChannelPowerGUI::makeUIConnections() void ChannelPowerGUI::updateAbsoluteCenterFrequency() { - setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset); + setStatusFrequency(m_settings.m_frequency); + if ( (m_basebandSampleRate > 1) + && ( (m_settings.m_inputFrequencyOffset >= m_basebandSampleRate / 2) + || (m_settings.m_inputFrequencyOffset < -m_basebandSampleRate / 2))) { + setStatusText("Frequency out of band"); + } else { + setStatusText(""); + } } diff --git a/plugins/channelrx/channelpower/channelpowergui.h b/plugins/channelrx/channelpower/channelpowergui.h index a145def73..9715bd81b 100644 --- a/plugins/channelrx/channelpower/channelpowergui.h +++ b/plugins/channelrx/channelpower/channelpowergui.h @@ -92,6 +92,7 @@ private: void displaySettings(); bool handleMessage(const Message& message); void makeUIConnections(); + void calcOffset(); void updateAbsoluteCenterFrequency(); void on_clearMeasurements_clicked(); @@ -99,6 +100,7 @@ private: void enterEvent(EnterEventType*); private slots: + void on_frequencyMode_currentIndexChanged(int index); void on_deltaFrequency_changed(qint64 value); void on_rfBW_changed(qint64 value); void on_clearChannelPower_clicked(); diff --git a/plugins/channelrx/channelpower/channelpowergui.ui b/plugins/channelrx/channelpower/channelpowergui.ui index 3adbd1c2a..97631aeeb 100644 --- a/plugins/channelrx/channelpower/channelpowergui.ui +++ b/plugins/channelrx/channelpower/channelpowergui.ui @@ -74,16 +74,32 @@ 2 - + - 16 + 40 0 - - Df + + + 40 + 16777215 + + + Select frequency entry mode. + + + + Δf + + + + + f + + diff --git a/plugins/channelrx/channelpower/channelpowersettings.cpp b/plugins/channelrx/channelpower/channelpowersettings.cpp index 5fc0fa06e..b8f97429c 100644 --- a/plugins/channelrx/channelpower/channelpowersettings.cpp +++ b/plugins/channelrx/channelpower/channelpowersettings.cpp @@ -36,6 +36,8 @@ void ChannelPowerSettings::resetToDefaults() m_rfBandwidth = 10000.0f; m_pulseThreshold= -50.0f; m_averagePeriodUS = 100000; + m_frequencyMode = Offset; + m_frequency = 0; m_rgbColor = QColor(102, 40, 220).rgb(); m_title = "Channel Power"; m_streamIndex = 0; @@ -56,6 +58,8 @@ QByteArray ChannelPowerSettings::serialize() const s.writeFloat(2, m_rfBandwidth); s.writeFloat(3, m_pulseThreshold); s.writeS32(4, m_averagePeriodUS); + s.writeS32(5, (int) m_frequencyMode); + s.writeS64(6, m_frequency); s.writeU32(21, m_rgbColor); s.writeString(22, m_title); @@ -102,6 +106,8 @@ bool ChannelPowerSettings::deserialize(const QByteArray& data) d.readFloat(2, &m_rfBandwidth, 10000.0f); d.readFloat(3, &m_pulseThreshold, 50.0f); d.readS32(4, &m_averagePeriodUS, 100000); + d.readS32(5, (int *) &m_frequencyMode, (int) Offset); + d.readS64(6, &m_frequency); d.readU32(21, &m_rgbColor, QColor(102, 40, 220).rgb()); d.readString(22, &m_title, "Channel Power"); @@ -161,6 +167,18 @@ void ChannelPowerSettings::applySettings(const QStringList& settingsKeys, const if (settingsKeys.contains("averagePeriodUS")) { m_averagePeriodUS = settings.m_averagePeriodUS; } + if (settingsKeys.contains("frequencyMode")) { + m_frequencyMode = settings.m_frequencyMode; + } + if (settingsKeys.contains("frequency")) { + m_frequency = settings.m_frequency; + } + if (settingsKeys.contains("rgbColor")) { + m_rgbColor = settings.m_rgbColor; + } + if (settingsKeys.contains("title")) { + m_title = settings.m_title; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -191,6 +209,12 @@ QString ChannelPowerSettings::getDebugString(const QStringList& settingsKeys, bo if (settingsKeys.contains("averagePeriodUS") || force) { ostr << " m_averagePeriodUS: " << m_averagePeriodUS; } + if (settingsKeys.contains("frequencyMode") || force) { + ostr << " m_frequencyMode: " << m_frequencyMode; + } + if (settingsKeys.contains("frequency") || force) { + ostr << " m_frequency: " << m_frequency; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } @@ -200,7 +224,7 @@ QString ChannelPowerSettings::getDebugString(const QStringList& settingsKeys, bo if (settingsKeys.contains("reverseAPIPort") || force) { ostr << " m_reverseAPIPort: " << m_reverseAPIPort; } - if (settingsKeys.contains("everseAPIDeviceIndex") || force) { + if (settingsKeys.contains("reverseAPIDeviceIndex") || force) { ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex; } diff --git a/plugins/channelrx/channelpower/channelpowersettings.h b/plugins/channelrx/channelpower/channelpowersettings.h index a875c36bb..b8a9d9dbb 100644 --- a/plugins/channelrx/channelpower/channelpowersettings.h +++ b/plugins/channelrx/channelpower/channelpowersettings.h @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Edouard Griffiths, F4EXB. // -// Copyright (C) 2023 Jon Beniston, M7RCE // +// Copyright (C) 2023-2024 Jon Beniston, M7RCE // // // // 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 // @@ -32,6 +32,11 @@ struct ChannelPowerSettings Real m_rfBandwidth; float m_pulseThreshold; int m_averagePeriodUS; + enum FrequencyMode { + Offset, + Absolute + } m_frequencyMode; + qint64 m_frequency; quint32 m_rgbColor; QString m_title;