mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-05-23 08:37:06 -04:00
Freq scanner: implemented device frequency locking
This commit is contained in:
parent
ceb602283a
commit
98c703bfbf
@ -314,7 +314,7 @@ void FreqScanner::initScan()
|
||||
// }
|
||||
mute(m_scanDeviceSetIndex, m_scanChannelIndex);
|
||||
|
||||
if (m_centerFrequency != m_stepStartFrequency) {
|
||||
if (!m_settings.m_lockDeviceFrequency && (m_centerFrequency != m_stepStartFrequency)) {
|
||||
setDeviceCenterFrequency(m_stepStartFrequency);
|
||||
}
|
||||
|
||||
@ -386,54 +386,77 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
|
||||
}
|
||||
|
||||
// Calculate next center frequency
|
||||
bool complete = false; // Have all frequencies been scanned?
|
||||
bool freqInRange = false;
|
||||
const bool lockDeviceFrequency = m_settings.m_lockDeviceFrequency;
|
||||
const qint64 currentCenterFrequency = m_centerFrequency;
|
||||
bool complete = lockDeviceFrequency; // Have all frequencies been scanned?
|
||||
bool freqInRange = lockDeviceFrequency;
|
||||
qint64 nextCenterFrequency = m_centerFrequency;
|
||||
int usableBW = (m_scannerSampleRate * 3 / 4) & ~1;
|
||||
int nextFrequencyIndex = 0;
|
||||
do
|
||||
int nextFrequencyIndex = -1;
|
||||
const auto isInCurrentScanRange = [currentCenterFrequency, usableBW](qint64 frequency)
|
||||
{
|
||||
if (nextCenterFrequency + usableBW / 2 > m_stepStopFrequency)
|
||||
{
|
||||
nextCenterFrequency = m_stepStartFrequency;
|
||||
complete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCenterFrequency += usableBW;
|
||||
complete = false;
|
||||
}
|
||||
return (frequency >= currentCenterFrequency - usableBW / 2)
|
||||
&& (frequency < currentCenterFrequency + usableBW / 2);
|
||||
};
|
||||
|
||||
// Are any frequencies in this new range?
|
||||
if (!lockDeviceFrequency)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (nextCenterFrequency + usableBW / 2 > m_stepStopFrequency)
|
||||
{
|
||||
nextCenterFrequency = m_stepStartFrequency;
|
||||
complete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCenterFrequency += usableBW;
|
||||
complete = false;
|
||||
}
|
||||
|
||||
// Are any frequencies in this new range?
|
||||
for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
|
||||
{
|
||||
if (m_settings.m_frequencySettings[i].m_enabled
|
||||
&& (m_settings.m_frequencySettings[i].m_frequency >= nextCenterFrequency - usableBW / 2)
|
||||
&& (m_settings.m_frequencySettings[i].m_frequency < nextCenterFrequency + usableBW / 2))
|
||||
{
|
||||
freqInRange = true;
|
||||
nextFrequencyIndex = i;
|
||||
|
||||
// Do we need to realign for frequencies with wider bandwidths than default
|
||||
if (!m_settings.m_frequencySettings[i].m_channelBandwidth.isEmpty())
|
||||
{
|
||||
bool ok;
|
||||
int channelBW = m_settings.m_frequencySettings[i].m_channelBandwidth.toInt(&ok);
|
||||
if (ok)
|
||||
{
|
||||
if (channelBW >= usableBW) {
|
||||
nextCenterFrequency = m_settings.m_frequencySettings[i].m_frequency;
|
||||
} else if (m_settings.m_frequencySettings[i].m_frequency - channelBW / 2 < nextCenterFrequency - usableBW / 2) {
|
||||
nextCenterFrequency = m_settings.m_frequencySettings[i].m_frequency - channelBW / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!complete && !freqInRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
|
||||
{
|
||||
if (m_settings.m_frequencySettings[i].m_enabled
|
||||
&& (m_settings.m_frequencySettings[i].m_frequency >= nextCenterFrequency - usableBW / 2)
|
||||
&& (m_settings.m_frequencySettings[i].m_frequency < nextCenterFrequency + usableBW / 2))
|
||||
&& isInCurrentScanRange(m_settings.m_frequencySettings[i].m_frequency))
|
||||
{
|
||||
freqInRange = true;
|
||||
nextFrequencyIndex = i;
|
||||
|
||||
// Do we need to realign for frequencies with wider bandwidths than default
|
||||
if (!m_settings.m_frequencySettings[i].m_channelBandwidth.isEmpty())
|
||||
{
|
||||
bool ok;
|
||||
int channelBW = m_settings.m_frequencySettings[i].m_channelBandwidth.toInt(&ok);
|
||||
if (ok)
|
||||
{
|
||||
if (channelBW >= usableBW) {
|
||||
nextCenterFrequency = m_settings.m_frequencySettings[i].m_frequency;
|
||||
} else if (m_settings.m_frequencySettings[i].m_frequency - channelBW / 2 < nextCenterFrequency - usableBW / 2) {
|
||||
nextCenterFrequency = m_settings.m_frequencySettings[i].m_frequency - channelBW / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!complete && !freqInRange);
|
||||
|
||||
if (complete || (m_settings.m_mode == FreqScannerSettings::MULTIPLEX))
|
||||
{
|
||||
@ -454,8 +477,11 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
|
||||
|
||||
if (m_settings.m_mode == FreqScannerSettings::MULTIPLEX)
|
||||
{
|
||||
activeFrequencySettings = &m_settings.m_frequencySettings[nextFrequencyIndex];
|
||||
frequency = activeFrequencySettings->m_frequency;
|
||||
if (nextFrequencyIndex >= 0)
|
||||
{
|
||||
activeFrequencySettings = &m_settings.m_frequencySettings[nextFrequencyIndex];
|
||||
frequency = activeFrequencySettings->m_frequency;
|
||||
}
|
||||
}
|
||||
else if (m_settings.m_priority == FreqScannerSettings::MAX_POWER)
|
||||
{
|
||||
@ -464,6 +490,10 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
|
||||
// Find frequency with max power that exceeds thresholds
|
||||
for (int i = 0; i < m_scanResults.size(); i++)
|
||||
{
|
||||
if (lockDeviceFrequency && !isInCurrentScanRange(m_scanResults[i].m_frequency)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
frequencySettings = m_settings.getFrequencySettings(m_scanResults[i].m_frequency);
|
||||
Real threshold = m_settings.getThreshold(frequencySettings);
|
||||
|
||||
@ -486,6 +516,11 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
|
||||
{
|
||||
int j = m_settings.m_voiceSquelchType == FreqScannerSettings::VoiceSquelchType::VoiceLsb ?
|
||||
m_scanResults.size()-1 - i : i;
|
||||
|
||||
if (lockDeviceFrequency && !isInCurrentScanRange(m_scanResults[j].m_frequency)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
frequencySettings = m_settings.getFrequencySettings(m_scanResults[j].m_frequency);
|
||||
Real threshold = m_settings.getThreshold(frequencySettings);
|
||||
|
||||
@ -520,20 +555,23 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
|
||||
}
|
||||
|
||||
// Ensure we have minimum offset from DC
|
||||
if (offset >= 0)
|
||||
if (!lockDeviceFrequency)
|
||||
{
|
||||
while (offset < m_settings.m_channelFrequencyOffset)
|
||||
if (offset >= 0)
|
||||
{
|
||||
nextCenterFrequency -= m_settings.m_channelBandwidth;
|
||||
offset += m_settings.m_channelBandwidth;
|
||||
while (offset < m_settings.m_channelFrequencyOffset)
|
||||
{
|
||||
nextCenterFrequency -= m_settings.m_channelBandwidth;
|
||||
offset += m_settings.m_channelBandwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (abs(offset) < m_settings.m_channelFrequencyOffset)
|
||||
else
|
||||
{
|
||||
nextCenterFrequency += m_settings.m_channelBandwidth;
|
||||
offset -= m_settings.m_channelBandwidth;
|
||||
while (abs(offset) < m_settings.m_channelFrequencyOffset)
|
||||
{
|
||||
nextCenterFrequency += m_settings.m_channelBandwidth;
|
||||
offset -= m_settings.m_channelBandwidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,7 +637,12 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
|
||||
}
|
||||
}
|
||||
|
||||
if (nextCenterFrequency != m_centerFrequency) {
|
||||
if (m_settings.m_lockDeviceFrequency) {
|
||||
nextCenterFrequency = m_centerFrequency;
|
||||
}
|
||||
|
||||
if (nextCenterFrequency != m_centerFrequency)
|
||||
{
|
||||
setDeviceCenterFrequency(nextCenterFrequency);
|
||||
}
|
||||
|
||||
|
||||
@ -197,6 +197,8 @@ bool FreqScannerGUI::handleMessage(const Message& message)
|
||||
int row = item->row();
|
||||
QTableWidgetItem* powerItem = ui->table->item(row, COL_POWER);
|
||||
powerItem->setData(Qt::DisplayRole, results[i].m_power);
|
||||
QTableWidgetItem* vadItem = ui->table->item(row, COL_VAD);
|
||||
vadItem->setData(Qt::DisplayRole, results[i].m_voiceActivityLevel);
|
||||
FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(freq);
|
||||
Real threshold = m_settings.getThreshold(frequencySettings);
|
||||
bool active = results[i].m_power >= threshold;
|
||||
@ -405,6 +407,12 @@ void FreqScannerGUI::on_voiceSquelchType_currentIndexChanged(int index)
|
||||
applySettings(settingsKeys);
|
||||
}
|
||||
|
||||
void FreqScannerGUI::on_lockDeviceFrequency_toggled(bool checked)
|
||||
{
|
||||
m_settings.m_lockDeviceFrequency = checked;
|
||||
applySetting("lockDeviceFrequency");
|
||||
}
|
||||
|
||||
void FreqScannerGUI::on_priority_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_priority = (FreqScannerSettings::Priority)index;
|
||||
@ -584,6 +592,7 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
|
||||
|
||||
ui->table->setItemDelegateForColumn(COL_FREQUENCY, new FrequencyDelegate("Auto", 3, true, ui->table));
|
||||
ui->table->setItemDelegateForColumn(COL_POWER, new DecimalDelegate(1, ui->table));
|
||||
ui->table->setItemDelegateForColumn(COL_VAD, new DecimalDelegate(2, ui->table));
|
||||
ui->table->setItemDelegateForColumn(COL_CHANNEL_BW, new Int64Delegate(0, 10000000, ui->table));
|
||||
ui->table->setItemDelegateForColumn(COL_TH, new DecimalDelegate(1, -120.0, 0.0, ui->table));
|
||||
ui->table->setItemDelegateForColumn(COL_SQ, new DecimalDelegate(1, -120.0, 0.0, ui->table));
|
||||
@ -641,6 +650,7 @@ void FreqScannerGUI::displaySettings()
|
||||
ui->channels->setCurrentIndex(channelIndex);
|
||||
}
|
||||
ui->deltaFrequency->setValue(m_settings.m_channelFrequencyOffset);
|
||||
ui->deviceFreqLock->setChecked(m_settings.m_lockDeviceFrequency);
|
||||
ui->channelBandwidth->setValue(m_settings.m_channelBandwidth);
|
||||
ui->channelShift->setValue(m_settings.m_channelShift);
|
||||
ui->scanTime->setValue(m_settings.m_scanTime * 10.0);
|
||||
@ -740,6 +750,10 @@ void FreqScannerGUI::addRow(const FreqScannerSettings::FrequencySettings& freque
|
||||
powerItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
ui->table->setItem(row, COL_POWER, powerItem);
|
||||
|
||||
QTableWidgetItem* vadItem = new QTableWidgetItem();
|
||||
vadItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
ui->table->setItem(row, COL_VAD, vadItem);
|
||||
|
||||
QTableWidgetItem *activeCountItem = new QTableWidgetItem();
|
||||
activeCountItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
ui->table->setItem(row, COL_ACTIVE_COUNT, activeCountItem);
|
||||
@ -1296,6 +1310,7 @@ void FreqScannerGUI::resizeTable()
|
||||
ui->table->setItem(row, COL_ANNOTATION, new QTableWidgetItem("London VOLMET"));
|
||||
ui->table->setItem(row, COL_ENABLE, new QTableWidgetItem("Enable"));
|
||||
ui->table->setItem(row, COL_POWER, new QTableWidgetItem("-100.0"));
|
||||
ui->table->setItem(row, COL_VAD, new QTableWidgetItem("0.00"));
|
||||
ui->table->setItem(row, COL_ACTIVE_COUNT, new QTableWidgetItem("10000"));
|
||||
ui->table->setItem(row, COL_NOTES, new QTableWidgetItem("A channel name"));
|
||||
ui->table->setItem(row, COL_CHANNEL, new QTableWidgetItem("Enter some notes"));
|
||||
@ -1318,6 +1333,7 @@ void FreqScannerGUI::makeUIConnections()
|
||||
QObject::connect(ui->thresh, &QDial::valueChanged, this, &FreqScannerGUI::on_thresh_valueChanged);
|
||||
QObject::connect(ui->voiceSquelch, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_voiceSquelchType_currentIndexChanged);
|
||||
QObject::connect(ui->voiceThreshold, &QDial::valueChanged, this, &FreqScannerGUI::on_voiceThreshold_valueChanged);
|
||||
QObject::connect(ui->deviceFreqLock, &QToolButton::toggled, this, &FreqScannerGUI::on_lockDeviceFrequency_toggled);
|
||||
QObject::connect(ui->priority, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_priority_currentIndexChanged);
|
||||
QObject::connect(ui->measurement, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_measurement_currentIndexChanged);
|
||||
QObject::connect(ui->mode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_mode_currentIndexChanged);
|
||||
|
||||
@ -115,6 +115,7 @@ private:
|
||||
COL_ANNOTATION,
|
||||
COL_ENABLE,
|
||||
COL_POWER,
|
||||
COL_VAD,
|
||||
COL_ACTIVE_COUNT,
|
||||
COL_NOTES,
|
||||
COL_CHANNEL,
|
||||
@ -134,6 +135,7 @@ private slots:
|
||||
void on_thresh_valueChanged(int value);
|
||||
void on_voiceThreshold_valueChanged(int value);
|
||||
void on_voiceSquelchType_currentIndexChanged(int index);
|
||||
void on_lockDeviceFrequency_toggled(bool checked);
|
||||
void on_priority_currentIndexChanged(int index);
|
||||
void on_measurement_currentIndexChanged(int index);
|
||||
void on_mode_currentIndexChanged(int index);
|
||||
|
||||
@ -157,6 +157,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="deviceFreqLock">
|
||||
<property name="toolTip">
|
||||
<string>Lock device frequency to current value</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="Line" name="line">
|
||||
<property name="orientation">
|
||||
@ -302,7 +320,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2000</number>
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
@ -795,6 +813,14 @@
|
||||
<string>Channel power in decibels during the previous scan</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>VAD</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Voice level</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Active Count</string>
|
||||
|
||||
@ -48,6 +48,7 @@ void FreqScannerSettings::resetToDefaults()
|
||||
m_tuneTime = 100;
|
||||
m_voiceSquelchThreshold = 0.5f;
|
||||
m_voiceSquelchType = None;
|
||||
m_lockDeviceFrequency = false;
|
||||
m_priority = MAX_POWER;
|
||||
m_measurement = PEAK;
|
||||
m_mode = CONTINUOUS;
|
||||
@ -89,6 +90,7 @@ QByteArray FreqScannerSettings::serialize() const
|
||||
s.writeS32(14, (int)m_mode);
|
||||
s.writeList(15, m_frequencySettings);
|
||||
s.writeS32(16, m_channelShift);
|
||||
s.writeBool(17, m_lockDeviceFrequency);
|
||||
|
||||
s.writeList(20, m_columnIndexes);
|
||||
s.writeList(21, m_columnSizes);
|
||||
@ -145,6 +147,7 @@ bool FreqScannerSettings::deserialize(const QByteArray& data)
|
||||
d.readS32(14, (int*)&m_mode, (int)CONTINUOUS);
|
||||
d.readList(15, &m_frequencySettings);
|
||||
d.readS32(16, &m_channelShift, 0);
|
||||
d.readBool(17, &m_lockDeviceFrequency, false);
|
||||
|
||||
if (m_frequencySettings.size() == 0)
|
||||
{
|
||||
@ -234,6 +237,9 @@ void FreqScannerSettings::applySettings(const QStringList& settingsKeys, const F
|
||||
if (settingsKeys.contains("voiceSquelchType")) {
|
||||
m_voiceSquelchType = settings.m_voiceSquelchType;
|
||||
}
|
||||
if (settingsKeys.contains("lockDeviceFrequency")) {
|
||||
m_lockDeviceFrequency = settings.m_lockDeviceFrequency;
|
||||
}
|
||||
if (settingsKeys.contains("frequencySettings")) {
|
||||
m_frequencySettings = settings.m_frequencySettings;
|
||||
}
|
||||
@ -321,6 +327,9 @@ QString FreqScannerSettings::getDebugString(const QStringList& settingsKeys, boo
|
||||
if (settingsKeys.contains("voiceSquelchType") || force) {
|
||||
ostr << " m_voiceSquelchType: " << m_voiceSquelchType;
|
||||
}
|
||||
if (settingsKeys.contains("lockDeviceFrequency") || force) {
|
||||
ostr << " m_lockDeviceFrequency: " << m_lockDeviceFrequency;
|
||||
}
|
||||
if (settingsKeys.contains("frequencySettings") || force)
|
||||
{
|
||||
QStringList s;
|
||||
|
||||
@ -74,6 +74,8 @@ struct FreqScannerSettings
|
||||
SCAN_ONLY,
|
||||
MULTIPLEX
|
||||
} m_mode; //!< Whether to run a single or many scans
|
||||
bool m_lockDeviceFrequency; //!< Whether to lock device frequency to the initial center frequency of the first scan,
|
||||
//!< or allow it to be shifted by the channel shift setting
|
||||
|
||||
QList<int> m_columnIndexes;//!< How the columns are ordered in the table
|
||||
QList<int> m_columnSizes; //!< Size of the coumns in the table
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user