diff --git a/plugins/channelrx/freqscanner/freqscanner.cpp b/plugins/channelrx/freqscanner/freqscanner.cpp
index fa8628b2a..54cf255f2 100644
--- a/plugins/channelrx/freqscanner/freqscanner.cpp
+++ b/plugins/channelrx/freqscanner/freqscanner.cpp
@@ -249,6 +249,7 @@ bool FreqScanner::handleMessage(const Message& cmd)
     }
     else if (MsgStartScan::match(cmd))
     {
+        muteAll();
         startScan();
 
         return true;
@@ -302,6 +303,9 @@ void FreqScanner::setDeviceCenterFrequency(qint64 frequency)
 
 void FreqScanner::initScan()
 {
+    if (m_scanChannelIndex < 0) {
+        applyChannelSetting(m_settings.m_channel);
+    }
     ChannelWebAPIUtils::setAudioMute(m_scanDeviceSetIndex, m_scanChannelIndex, true);
 
     if (m_centerFrequency != m_stepStartFrequency) {
@@ -319,7 +323,6 @@ void FreqScanner::initScan()
 
 void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<MsgScanResult::ScanResult>& results)
 {
-
     switch (m_state)
     {
     case IDLE:
@@ -329,10 +332,10 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
         {
             // Create ordered list of frequencies to scan
             QList<qint64> frequencies;
-            for (int i = 0; i < m_settings.m_frequencies.size(); i++)
+            for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
             {
-                if (m_settings.m_enabled[i]) {
-                    frequencies.append(m_settings.m_frequencies[i]);
+                if (m_settings.m_frequencySettings[i].m_enabled) {
+                    frequencies.append(m_settings.m_frequencySettings[i].m_frequency);
                 }
             }
             std::sort(frequencies.begin(), frequencies.end());
@@ -390,11 +393,11 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
                 }
 
                 // Are any frequencies in this new range?
-                for (int i = 0; i < m_settings.m_frequencies.size(); i++)
+                for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
                 {
-                    if (m_settings.m_enabled[i]
-                        && (m_settings.m_frequencies[i] >= nextCenterFrequency - usableBW / 2)
-                        && (m_settings.m_frequencies[i] < nextCenterFrequency + usableBW / 2))
+                    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;
                         break;
@@ -416,51 +419,52 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
                         m_guiMessageQueue->push(msg);
                     }
 
-                    int frequency = m_scanResults[0].m_frequency;
-                    Real maxPower = m_scanResults[0].m_power;
+                    int frequency = -1;
+                    FreqScannerSettings::FrequencySettings *frequencySettings = nullptr;
+                    FreqScannerSettings::FrequencySettings *activeFrequencySettings = nullptr;
 
                     if (m_settings.m_priority == FreqScannerSettings::MAX_POWER)
                     {
-                        // Find frequency with max power
-                        for (int i = 1; i < m_scanResults.size(); i++)
+                        Real maxPower = -200.0f;
+
+                        // Find frequency with max power that exceeds thresholds
+                        for (int i = 0; i < m_scanResults.size(); i++)
                         {
-                            if (m_scanResults[i].m_power > maxPower)
+                            frequencySettings = m_settings.getFrequencySettings(m_scanResults[i].m_frequency);
+                            Real threshold = m_settings.getThreshold(frequencySettings);
+                            if (m_scanResults[i].m_power >= threshold)
                             {
-                                frequency = m_scanResults[i].m_frequency;
-                                maxPower = m_scanResults[i].m_power;
+                                if (!activeFrequencySettings || (m_scanResults[i].m_power > maxPower))
+                                {
+                                    frequency = m_scanResults[i].m_frequency;
+                                    maxPower = m_scanResults[i].m_power;
+                                    activeFrequencySettings = frequencySettings;
+                                }
                             }
                         }
                     }
                     else
                     {
                         // Find first frequency in list above threshold
-                        for (int j = 0; j < m_settings.m_frequencies.size(); j++)
+                        for (int i = 0; i < m_scanResults.size(); i++)
                         {
-                            for (int i = 0; i < m_scanResults.size(); i++)
+                            frequencySettings = m_settings.getFrequencySettings(m_scanResults[i].m_frequency);
+                            Real threshold = m_settings.getThreshold(frequencySettings);
+                            if (m_scanResults[i].m_power >= threshold)
                             {
-                                if (m_scanResults[i].m_frequency == m_settings.m_frequencies[j])
-                                {
-                                    if (m_scanResults[i].m_power >= m_settings.m_threshold)
-                                    {
-                                        frequency = m_scanResults[i].m_frequency;
-                                        maxPower = m_scanResults[i].m_power;
-                                        goto found_freq;
-                                    }
-                                }
+                                frequency = m_scanResults[i].m_frequency;
+                                activeFrequencySettings = frequencySettings;
+                                break;
                             }
                         }
-                        found_freq: ;
                     }
 
                     if (m_settings.m_mode != FreqScannerSettings::SCAN_ONLY)
                     {
-                        // Is power above threshold
-                        if (maxPower >= m_settings.m_threshold)
+                        // Were any frequencies found to be active?
+                        //if (maxPower >= m_settings.m_threshold)
+                        if (activeFrequencySettings)
                         {
-                            if (m_guiMessageQueue) {
-                                m_guiMessageQueue->push(MsgReportActiveFrequency::create(frequency));
-                            }
-
                             // Tune device/channel to frequency
                             int offset;
                             if ((frequency < m_centerFrequency - usableBW / 2) || (frequency >= m_centerFrequency + usableBW / 2))
@@ -494,11 +498,28 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
 
                             //qDebug() << "Tuning to active freq:" << frequency << "m_centerFrequency" << m_centerFrequency << "nextCenterFrequency" << nextCenterFrequency << "offset: " << offset << "deviceset: R" << m_scanDeviceSetIndex << ":" << m_scanChannelIndex;
 
+                            QString channel = m_settings.m_channel;
+                            if (!activeFrequencySettings->m_channel.isEmpty()) {
+                                channel = activeFrequencySettings->m_channel;
+                            }
+                            applyChannelSetting(channel);
+
+                            // Tune the channel
                             ChannelWebAPIUtils::setFrequencyOffset(m_scanDeviceSetIndex, m_scanChannelIndex, offset);
 
                             // Unmute the channel
                             ChannelWebAPIUtils::setAudioMute(m_scanDeviceSetIndex, m_scanChannelIndex, false);
 
+                            // Apply squelch
+                            if (!activeFrequencySettings->m_squelch.isEmpty())
+                            {
+                                bool ok;
+                                Real squelch = activeFrequencySettings->m_squelch.toFloat(&ok);
+                                if (ok) {
+                                    ChannelWebAPIUtils::patchChannelSetting(m_scanDeviceSetIndex, m_scanChannelIndex, "squelch", squelch);
+                                }
+                            }
+
                             m_activeFrequency = frequency;
 
                             if (m_settings.m_mode == FreqScannerSettings::SINGLE)
@@ -514,11 +535,16 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
                                 // Wait for transmission to finish
                                 m_state = WAIT_FOR_END_TX;
                             }
+
+                            // Becareful to only do this at the end here, as it can recursively call handleMessage with new settings
+                            if (m_guiMessageQueue) {
+                                m_guiMessageQueue->push(MsgReportActiveFrequency::create(m_activeFrequency));
+                            }
                         }
                         else
                         {
                             if (m_guiMessageQueue) {
-                                m_guiMessageQueue->push(MsgStatus::create(QString("Scanning: No active channels - Max power %1 dB").arg(maxPower, 0, 'f', 1)));
+                                m_guiMessageQueue->push(MsgStatus::create("Scanning..."));
                             }
                         }
                     }
@@ -545,7 +571,9 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
                 }
 
                 // Wait until power drops below threshold
-                if (results[i].m_power < m_settings.m_threshold)
+                FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(m_activeFrequency);
+                Real threshold = m_settings.getThreshold(frequencySettings);
+                if (results[i].m_power < threshold)
                 {
                     m_timeoutTimer.setSingleShot(true);
                     m_timeoutTimer.start((int)(m_settings.m_retransmitTime * 1000.0));
@@ -566,7 +594,9 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
                 }
 
                 // Check if power has returned to being above threshold
-                if (results[i].m_power >= m_settings.m_threshold)
+                FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(m_activeFrequency);
+                Real threshold = m_settings.getThreshold(frequencySettings);
+                if (results[i].m_power >= threshold)
                 {
                     m_timeoutTimer.stop();
                     m_state = WAIT_FOR_END_TX;
@@ -598,6 +628,9 @@ void FreqScanner::calcScannerSampleRate(int channelBW, int basebandSampleRate, i
     // But ensure we have several bins per channel
     // Adjust sample rate, to ensure we don't get massive FFT size
     scannerSampleRate = basebandSampleRate;
+    if (scannerSampleRate < channelBW) {
+        channelBW = scannerSampleRate; // Prevent divide by 0
+    }
     while (fftSize / (scannerSampleRate / channelBW) < minBinsPerChannel)
     {
         if (fftSize == maxFFTSize) {
@@ -623,6 +656,46 @@ void FreqScanner::setCenterFrequency(qint64 frequency)
     }
 }
 
+// Mute all channels
+void FreqScanner::muteAll()
+{
+    QStringList channels;
+
+    channels.append(m_settings.m_channel);
+    for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
+    {
+        QString channel = m_settings.m_frequencySettings[i].m_channel;
+        if (!channel.isEmpty() && !channels.contains(channel)) {
+            channels.append(channel);
+        }
+    }
+
+    const QRegExp re("R([0-9]+):([0-9]+)");
+    for (const auto& channel : channels)
+    {
+        if (re.indexIn(channel) >= 0)
+        {
+            int deviceSetIndex = re.capturedTexts()[1].toInt();
+            int scanChannelIndex = re.capturedTexts()[2].toInt();
+            ChannelWebAPIUtils::setAudioMute(deviceSetIndex, scanChannelIndex, true);
+        }
+    }
+}
+
+void FreqScanner::applyChannelSetting(const QString& channel)
+{
+    const QRegExp re("R([0-9]+):([0-9]+)");
+    if (re.indexIn(channel) >= 0)
+    {
+        m_scanDeviceSetIndex = re.capturedTexts()[1].toInt();
+        m_scanChannelIndex = re.capturedTexts()[2].toInt();
+    }
+    else
+    {
+        qDebug() << "FreqScanner::applySettings: Failed to parse channel" << channel;
+    }
+}
+
 void FreqScanner::applySettings(const FreqScannerSettings& settings, const QStringList& settingsKeys, bool force)
 {
     qDebug() << "FreqScanner::applySettings:"
@@ -640,20 +713,6 @@ void FreqScanner::applySettings(const FreqScannerSettings& settings, const QStri
         }
     }
 
-    if (settingsKeys.contains("channel") || force)
-    {
-        const QRegExp re("R([0-9]+):([0-9]+)");
-        if (re.indexIn(settings.m_channel) >= 0)
-        {
-            m_scanDeviceSetIndex = re.capturedTexts()[1].toInt();
-            m_scanChannelIndex = re.capturedTexts()[2].toInt();
-        }
-        else
-        {
-            qDebug() << "FreqScanner::applySettings: Failed to parse channel" << settings.m_channel;
-        }
-    }
-
     if (m_running)
     {
         FreqScannerBaseband::MsgConfigureFreqScannerBaseband *msg = FreqScannerBaseband::MsgConfigureFreqScannerBaseband::create(settings, settingsKeys, force);
@@ -670,7 +729,7 @@ void FreqScanner::applySettings(const FreqScannerSettings& settings, const QStri
         webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
     }
 
-    if (settingsKeys.contains("frequencies")
+    if (settingsKeys.contains("frequencySettings")
         || settingsKeys.contains("priority")
         || settingsKeys.contains("measurement")
         || settingsKeys.contains("mode")
@@ -784,21 +843,30 @@ void FreqScanner::webapiUpdateChannelSettings(
     }
     if (channelSettingsKeys.contains("frequencies"))
     {
-        settings.m_frequencies.clear();
-        settings.m_enabled.clear();
-        settings.m_notes.clear();
+        settings.m_frequencySettings.clear();
         QList<SWGSDRangel::SWGFreqScannerFrequency *> *frequencies = response.getFreqScannerSettings()->getFrequencies();
         if (frequencies)
         {
             for (const auto frequency : *frequencies)
             {
-                settings.m_frequencies.append(frequency->getFrequency());
-                settings.m_enabled.append((bool)frequency->getEnabled());
+                FreqScannerSettings::FrequencySettings freqSetting;
+                freqSetting.m_frequency = frequency->getFrequency();
                 if (frequency->getNotes()) {
-                    settings.m_notes.append(*frequency->getNotes());
-                } else {
-                    settings.m_notes.append("");
+                    freqSetting.m_notes = *frequency->getNotes();
                 }
+                if (frequency->getChannel()) {
+                    freqSetting.m_channel = *frequency->getChannel();
+                }
+                if (frequency->getChannelBandwidth()) {
+                    freqSetting.m_channelBandwidth = *frequency->getChannelBandwidth();
+                }
+                if (frequency->getThreshold()) {
+                    freqSetting.m_threshold = *frequency->getThreshold();
+                }
+                if (frequency->getSquelch()) {
+                    freqSetting.m_squelch = *frequency->getSquelch();
+                }
+                settings.m_frequencySettings.append(freqSetting);
             }
         }
     }
@@ -837,14 +905,26 @@ void FreqScanner::webapiUpdateChannelSettings(
 QList<SWGSDRangel::SWGFreqScannerFrequency *> *FreqScanner::createFrequencyList(const FreqScannerSettings& settings)
 {
     QList<SWGSDRangel::SWGFreqScannerFrequency *> *frequencies = new QList<SWGSDRangel::SWGFreqScannerFrequency *>();
-    for (int i = 0; i < settings.m_frequencies.size(); i++)
+    for (int i = 0; i < settings.m_frequencySettings.size(); i++)
     {
         SWGSDRangel::SWGFreqScannerFrequency *frequency = new SWGSDRangel::SWGFreqScannerFrequency();
         frequency->init();
-        frequency->setFrequency(settings.m_frequencies[i]);
-        frequency->setEnabled(settings.m_enabled[i]);
-        if (!settings.m_notes[i].isEmpty()) {
-            frequency->setNotes(new QString(settings.m_notes[i]));
+        frequency->setFrequency(settings.m_frequencySettings[i].m_frequency);
+        frequency->setEnabled(settings.m_frequencySettings[i].m_enabled);
+        if (!settings.m_frequencySettings[i].m_notes.isEmpty()) {
+            frequency->setNotes(new QString(settings.m_frequencySettings[i].m_notes));
+        }
+        if (!settings.m_frequencySettings[i].m_channel.isEmpty()) {
+            frequency->setChannel(new QString(settings.m_frequencySettings[i].m_channel));
+        }
+        if (!settings.m_frequencySettings[i].m_channelBandwidth.isEmpty()) {
+            frequency->setChannelBandwidth(new QString(settings.m_frequencySettings[i].m_channelBandwidth));
+        }
+        if (!settings.m_frequencySettings[i].m_threshold.isEmpty()) {
+            frequency->setThreshold(new QString(settings.m_frequencySettings[i].m_threshold));
+        }
+        if (!settings.m_frequencySettings[i].m_squelch.isEmpty()) {
+            frequency->setSquelch(new QString(settings.m_frequencySettings[i].m_squelch));
         }
         frequencies->append(frequency);
     }
diff --git a/plugins/channelrx/freqscanner/freqscanner.h b/plugins/channelrx/freqscanner/freqscanner.h
index 2a72796d2..7613e704d 100644
--- a/plugins/channelrx/freqscanner/freqscanner.h
+++ b/plugins/channelrx/freqscanner/freqscanner.h
@@ -407,6 +407,8 @@ private:
     void initScan();
     void processScanResults(const QDateTime& fftStartTime, const QList<MsgScanResult::ScanResult>& results);
     void setDeviceCenterFrequency(qint64 frequency);
+    void applyChannelSetting(const QString& channel);
+    void muteAll();
 
     static QList<SWGSDRangel::SWGFreqScannerFrequency *> *createFrequencyList(const FreqScannerSettings& settings);
 
diff --git a/plugins/channelrx/freqscanner/freqscannergui.cpp b/plugins/channelrx/freqscanner/freqscannergui.cpp
index cadc52692..a08247a79 100644
--- a/plugins/channelrx/freqscanner/freqscannergui.cpp
+++ b/plugins/channelrx/freqscanner/freqscannergui.cpp
@@ -22,6 +22,7 @@
 #include <QTableWidget>
 #include <QTableWidgetItem>
 #include <QRegExp>
+#include <QComboBox>
 
 #include "device/deviceset.h"
 #include "device/deviceuiset.h"
@@ -37,6 +38,7 @@
 #include "gui/dialogpositioner.h"
 #include "gui/decimaldelegate.h"
 #include "gui/frequencydelegate.h"
+#include "gui/int64delegate.h"
 #include "gui/glspectrum.h"
 #include "channel/channelwebapiutils.h"
 
@@ -103,9 +105,9 @@ bool FreqScannerGUI::handleMessage(const Message& message)
         m_basebandSampleRate = notif.getSampleRate();
         if (m_basebandSampleRate != 0)
         {
-            ui->deltaFrequency->setValueRange(true, 7, 0, m_basebandSampleRate/2);
+            ui->deltaFrequency->setValueRange(true, 8, 0, m_basebandSampleRate/2);
             ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2));
-            ui->channelBandwidth->setValueRange(true, 7, 0, m_basebandSampleRate);
+            ui->channelBandwidth->setValueRange(true, 8, 0, m_basebandSampleRate);
         }
         if (m_channelMarker.getBandwidth() == 0) {
             m_channelMarker.setBandwidth(m_basebandSampleRate);
@@ -116,7 +118,8 @@ bool FreqScannerGUI::handleMessage(const Message& message)
     else if (FreqScanner::MsgReportChannels::match(message))
     {
         FreqScanner::MsgReportChannels& report = (FreqScanner::MsgReportChannels&)message;
-        updateChannelsList(report.getChannels());
+        m_availableChannels = report.getChannels();
+        updateChannelsList(m_availableChannels);
         return true;
     }
     else if (FreqScanner::MsgStatus::match(message))
@@ -187,11 +190,14 @@ bool FreqScannerGUI::handleMessage(const Message& message)
         {
             qint64 freq = results[i].m_frequency;
             QList<QTableWidgetItem *> items = ui->table->findItems(QString::number(freq), Qt::MatchExactly);
-            for (auto item : items) {
+            for (auto item : items)
+            {
                 int row = item->row();
                 QTableWidgetItem* powerItem = ui->table->item(row, COL_POWER);
                 powerItem->setData(Qt::DisplayRole, results[i].m_power);
-                bool active = results[i].m_power >= m_settings.m_threshold;
+                FreqScannerSettings::FrequencySettings *frequencySettings = m_settings.getFrequencySettings(freq);
+                Real threshold = m_settings.getThreshold(frequencySettings);
+                bool active = results[i].m_power >= threshold;
                 if (active)
                 {
                     powerItem->setBackground(Qt::darkGreen);
@@ -206,10 +212,13 @@ bool FreqScannerGUI::handleMessage(const Message& message)
     return false;
 }
 
-void FreqScannerGUI::updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels)
+void FreqScannerGUI::updateChannelsCombo(QComboBox *combo, const QList<FreqScannerSettings::AvailableChannel>& channels, const QString& channel, bool empty)
 {
-    ui->channels->blockSignals(true);
-    ui->channels->clear();
+    combo->blockSignals(true);
+    combo->clear();
+    if (empty) {
+        combo->addItem("");
+    }
 
     for (const auto& channel : channels)
     {
@@ -217,21 +226,32 @@ void FreqScannerGUI::updateChannelsList(const QList<FreqScannerSettings::Availab
         if ((channel.m_deviceSetIndex == m_freqScanner->getDeviceSetIndex()) && (channel.m_channelIndex != m_freqScanner->getIndexInDeviceSet()))
         {
             QString name = QString("R%1:%2").arg(channel.m_deviceSetIndex).arg(channel.m_channelIndex);
-            ui->channels->addItem(name);
+            combo->addItem(name);
         }
     }
 
     // Channel can be created after this plugin, so select it
     // if the chosen channel appears
-    int channelIndex = ui->channels->findText(m_settings.m_channel);
+    int channelIndex = combo->findText(channel);
 
     if (channelIndex >= 0) {
-        ui->channels->setCurrentIndex(channelIndex);
+        combo->setCurrentIndex(channelIndex);
     } else {
-        ui->channels->setCurrentIndex(-1); // return to nothing selected
+        combo->setCurrentIndex(-1); // return to nothing selected
     }
 
-    ui->channels->blockSignals(false);
+    combo->blockSignals(false);
+}
+
+void FreqScannerGUI::updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels)
+{
+    updateChannelsCombo(ui->channels, channels, m_settings.m_channel, false);
+
+    for (int row = 0; row < ui->table->rowCount(); row++)
+    {
+        QComboBox *combo = qobject_cast<QComboBox *>(ui->table->cellWidget(row, COL_CHANNEL));
+        updateChannelsCombo(combo, channels, m_settings.m_frequencySettings[row].m_channel, true);
+    }
 }
 
 void FreqScannerGUI::on_channels_currentIndexChanged(int index)
@@ -412,10 +432,10 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
 
     ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
     ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
-    ui->deltaFrequency->setValueRange(true, 7, 0, 9999999);
+    ui->deltaFrequency->setValueRange(true, 8, 0, 9999999);
 
     ui->channelBandwidth->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
-    ui->channelBandwidth->setValueRange(true, 7, 0, 9999999);
+    ui->channelBandwidth->setValueRange(true, 8, 0, 9999999);
 
     m_channelMarker.setColor(Qt::yellow);
     m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
@@ -464,6 +484,9 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
 
     ui->table->setItemDelegateForColumn(COL_FREQUENCY, new FrequencyDelegate("Auto", 3));
     ui->table->setItemDelegateForColumn(COL_POWER, new DecimalDelegate(1));
+    ui->table->setItemDelegateForColumn(COL_CHANNEL_BW, new Int64Delegate(0, 10000000));
+    ui->table->setItemDelegateForColumn(COL_TH, new DecimalDelegate(1, -120.0, 0.0));
+    ui->table->setItemDelegateForColumn(COL_SQ, new DecimalDelegate(1, -120.0, 0.0));
 
     connect(m_deviceUISet->m_spectrum->getSpectrumView(), &GLSpectrumView::updateAnnotations, this, &FreqScannerGUI::updateAnnotations);
 }
@@ -531,9 +554,9 @@ void FreqScannerGUI::displaySettings()
 
     ui->table->blockSignals(true);
     ui->table->setRowCount(0);
-    for (int i = 0; i < m_settings.m_frequencies.size(); i++)
+    for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
     {
-        addRow(m_settings.m_frequencies[i], m_settings.m_enabled[i], m_settings.m_notes[i]);
+        addRow(m_settings.m_frequencySettings[i]);
         updateAnnotation(i);
     }
     ui->table->blockSignals(false);
@@ -584,7 +607,7 @@ void FreqScannerGUI::on_startStop_clicked(bool checked)
     }
 }
 
-void FreqScannerGUI::addRow(qint64 frequency, bool enabled, const QString& notes)
+void FreqScannerGUI::addRow(const FreqScannerSettings::FrequencySettings& frequencySettings)
 {
     int row = ui->table->rowCount();
     ui->table->setRowCount(row + 1);
@@ -594,11 +617,11 @@ void FreqScannerGUI::addRow(qint64 frequency, bool enabled, const QString& notes
     annotationItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
     ui->table->setItem(row, COL_ANNOTATION, annotationItem);
 
-    ui->table->setItem(row, COL_FREQUENCY, new QTableWidgetItem(QString("%1").arg(frequency)));
+    ui->table->setItem(row, COL_FREQUENCY, new QTableWidgetItem(QString("%1").arg(frequencySettings.m_frequency)));
 
     QTableWidgetItem *enableItem = new QTableWidgetItem();
     enableItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
-    enableItem->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
+    enableItem->setCheckState(frequencySettings.m_enabled ? Qt::Checked : Qt::Unchecked);
     ui->table->setItem(row, COL_ENABLE, enableItem);
 
     QTableWidgetItem* powerItem = new QTableWidgetItem();
@@ -610,13 +633,40 @@ void FreqScannerGUI::addRow(qint64 frequency, bool enabled, const QString& notes
     ui->table->setItem(row, COL_ACTIVE_COUNT, activeCountItem);
     activeCountItem->setData(Qt::DisplayRole, 0);
 
-    QTableWidgetItem* notesItem = new QTableWidgetItem(notes);
+    QTableWidgetItem* notesItem = new QTableWidgetItem(frequencySettings.m_notes);
     ui->table->setItem(row, COL_NOTES, notesItem);
+
+    QComboBox *channelComboBox = new QComboBox();
+    updateChannelsCombo(channelComboBox, m_availableChannels, frequencySettings.m_channel, true);
+    ui->table->setCellWidget(row, COL_CHANNEL, channelComboBox);
+    connect(channelComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FreqScannerGUI::on_table_channel_currentIndexChanged);
+
+    QTableWidgetItem* channelBandwidthItem = new QTableWidgetItem(frequencySettings.m_channelBandwidth);
+    ui->table->setItem(row, COL_CHANNEL_BW, channelBandwidthItem);
+
+    QTableWidgetItem* thresholdItem = new QTableWidgetItem(frequencySettings.m_threshold);
+    ui->table->setItem(row, COL_TH, thresholdItem);
+
+    QTableWidgetItem* squelchItem = new QTableWidgetItem(frequencySettings.m_squelch);
+    ui->table->setItem(row, COL_SQ, squelchItem);
+}
+
+void FreqScannerGUI::on_table_channel_currentIndexChanged(int index)
+{
+    if (index >= 0)
+    {
+        QComboBox *combo = qobject_cast<QComboBox *>(sender());
+        QModelIndex tableIndex = ui->table->indexAt(combo->pos());
+        on_table_cellChanged(tableIndex.row(), tableIndex.column());
+    }
 }
 
 void FreqScannerGUI::on_addSingle_clicked()
 {
-    addRow(0, true);
+    FreqScannerSettings::FrequencySettings frequencySettings;
+    frequencySettings.m_frequency = 0;
+    frequencySettings.m_enabled = true;
+    addRow(frequencySettings);
 }
 
 void FreqScannerGUI::on_addRange_clicked()
@@ -626,11 +676,15 @@ void FreqScannerGUI::on_addRange_clicked()
     if (dialog.exec())
     {
         blockApplySettings(true);
-        for (const auto f : dialog.m_frequencies) {
-            addRow(f, true);
+        for (const auto f : dialog.m_frequencies)
+        {
+            FreqScannerSettings::FrequencySettings frequencySettings;
+            frequencySettings.m_frequency = f;
+            frequencySettings.m_enabled = true;
+            addRow(frequencySettings);
         }
         blockApplySettings(false);
-        applySetting("frequencies");
+        applySetting("frequencySettings");
     }
 }
 
@@ -642,11 +696,9 @@ void FreqScannerGUI::on_remove_clicked()
     {
         int row = ui->table->row(item);
         ui->table->removeRow(row);
-        m_settings.m_frequencies.removeAt(row); // table_cellChanged isn't called for removeRow
-        m_settings.m_enabled.removeAt(row);
-        m_settings.m_notes.removeAt(row);
+        m_settings.m_frequencySettings.removeAt(row);
     }
-    applySetting("frequencies");
+    applySetting("frequencySettings");
 }
 
 void FreqScannerGUI::on_removeInactive_clicked()
@@ -656,12 +708,10 @@ void FreqScannerGUI::on_removeInactive_clicked()
         if (ui->table->item(i, COL_ACTIVE_COUNT)->data(Qt::DisplayRole).toInt() == 0)
         {
             ui->table->removeRow(i);
-            m_settings.m_frequencies.removeAt(i); // table_cellChanged isn't called for removeRow
-            m_settings.m_enabled.removeAt(i);
-            m_settings.m_notes.removeAt(i);
+            m_settings.m_frequencySettings.removeAt(i);
         }
     }
-    applySetting("frequencies");
+    applySetting("frequencySettings");
 }
 
 static QList<QTableWidgetItem*> takeRow(QTableWidget* table, int row)
@@ -730,26 +780,49 @@ void FreqScannerGUI::on_table_cellChanged(int row, int column)
         if (column == COL_FREQUENCY)
         {
             qint64 value = item->text().toLongLong();
-            while (m_settings.m_frequencies.size() <= row)
+            while (m_settings.m_frequencySettings.size() <= row)
             {
-                m_settings.m_frequencies.append(0);
-                m_settings.m_enabled.append(true);
-                m_settings.m_notes.append("");
+                FreqScannerSettings::FrequencySettings frequencySettings;
+                frequencySettings.m_frequency = 0;
+                frequencySettings.m_enabled = true;
+                m_settings.m_frequencySettings.append(frequencySettings);
             }
-            m_settings.m_frequencies[row] = value;
+            m_settings.m_frequencySettings[row].m_frequency = value;
             updateAnnotation(row);
-            applySetting("frequencies");
+            applySetting("frequencySettings");
         }
         else if (column == COL_ENABLE)
         {
-            m_settings.m_enabled[row] = item->checkState() == Qt::Checked;
-            applySetting("frequencies");
+            m_settings.m_frequencySettings[row].m_enabled = item->checkState() == Qt::Checked;
+            applySetting("frequencySettings");
         }
         else if (column == COL_NOTES)
         {
-            m_settings.m_notes[row] = item->text();
-            applySetting("frequencies");
+            m_settings.m_frequencySettings[row].m_notes = item->text();
+            applySetting("frequencySettings");
         }
+        else if (column == COL_CHANNEL_BW)
+        {
+            m_settings.m_frequencySettings[row].m_channelBandwidth = item->text();
+            applySetting("frequencySettings");
+        }
+        else if (column == COL_TH)
+        {
+            m_settings.m_frequencySettings[row].m_threshold = item->text();
+            applySetting("frequencySettings");
+        }
+        else if (column == COL_SQ)
+        {
+            m_settings.m_frequencySettings[row].m_squelch = item->text();
+            applySetting("frequencySettings");
+        }
+    }
+    else if (column == COL_CHANNEL)
+    {
+        QComboBox *combo = qobject_cast<QComboBox *>(ui->table->cellWidget(row, COL_CHANNEL));
+        m_settings.m_frequencySettings[row].m_channel = combo->currentText();
+        qDebug() << "Setting row" << row << "to" << combo->currentText();
+        applySetting("frequencySettings");
     }
 }
 
@@ -959,7 +1032,11 @@ void FreqScannerGUI::resizeTable()
     ui->table->setItem(row, COL_ENABLE, new QTableWidgetItem("Enable"));
     ui->table->setItem(row, COL_POWER, new QTableWidgetItem("-100.0"));
     ui->table->setItem(row, COL_ACTIVE_COUNT, new QTableWidgetItem("10000"));
-    ui->table->setItem(row, COL_NOTES, new QTableWidgetItem("Enter some notes"));
+    ui->table->setItem(row, COL_NOTES, new QTableWidgetItem("A channel name"));
+    ui->table->setItem(row, COL_CHANNEL, new QTableWidgetItem("Enter some notes"));
+    ui->table->setItem(row, COL_CHANNEL_BW, new QTableWidgetItem("100000000"));
+    ui->table->setItem(row, COL_TH, new QTableWidgetItem("-100.0"));
+    ui->table->setItem(row, COL_SQ, new QTableWidgetItem("-100.0"));
     ui->table->resizeColumnsToContents();
     ui->table->setRowCount(row);
 }
diff --git a/plugins/channelrx/freqscanner/freqscannergui.h b/plugins/channelrx/freqscanner/freqscannergui.h
index f3759fc08..edc598950 100644
--- a/plugins/channelrx/freqscanner/freqscannergui.h
+++ b/plugins/channelrx/freqscanner/freqscannergui.h
@@ -32,6 +32,7 @@ class BasebandSampleSink;
 class FreqScanner;
 class FreqScannerGUI;
 class QMenu;
+class QComboBox;
 
 namespace Ui {
     class FreqScannerGUI;
@@ -81,6 +82,8 @@ private:
 
     QMenu *m_menu;
 
+    QList<FreqScannerSettings::AvailableChannel> m_availableChannels;
+
     explicit FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
     virtual ~FreqScannerGUI();
 
@@ -92,9 +95,10 @@ private:
     bool handleMessage(const Message& message);
     void makeUIConnections();
     void updateAbsoluteCenterFrequency();
-    void addRow(qint64 frequency, bool enabled, const QString& notes = "");
+    void addRow(const FreqScannerSettings::FrequencySettings& frequencySettings);
     void updateAnnotation(int row);
     void updateAnnotations();
+    void updateChannelsCombo(QComboBox *combo, const QList<FreqScannerSettings::AvailableChannel>& channels, const QString& channel, bool empty);
     void updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels);
     void setAllEnabled(bool enable);
 
@@ -110,7 +114,11 @@ private:
         COL_ENABLE,
         COL_POWER,
         COL_ACTIVE_COUNT,
-        COL_NOTES
+        COL_NOTES,
+        COL_CHANNEL,
+        COL_CHANNEL_BW,
+        COL_TH,
+        COL_SQ
     };
 
 private slots:
@@ -125,6 +133,7 @@ private slots:
     void on_measurement_currentIndexChanged(int index);
     void on_mode_currentIndexChanged(int index);
     void on_table_cellChanged(int row, int column);
+    void on_table_channel_currentIndexChanged(int index);
     void table_customContextMenuRequested(QPoint pos);
     void table_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
     void table_sectionResized(int logicalIndex, int oldSize, int newSize);
diff --git a/plugins/channelrx/freqscanner/freqscannergui.ui b/plugins/channelrx/freqscanner/freqscannergui.ui
index 67e02cf93..76b287477 100644
--- a/plugins/channelrx/freqscanner/freqscannergui.ui
+++ b/plugins/channelrx/freqscanner/freqscannergui.ui
@@ -671,6 +671,46 @@
           <string>User notes about this frequency</string>
          </property>
         </column>
+        <column>
+         <property name="text">
+          <string>Channel</string>
+         </property>
+         <property name="toolTip">
+          <string>Frequency specific channel to tune
+
+Leave blank for common setting</string>
+         </property>
+        </column>
+        <column>
+         <property name="text">
+          <string>Ch BW (Hz)</string>
+         </property>
+         <property name="toolTip">
+          <string>Frequency specific channel BW
+
+Leave blank to use common setting</string>
+         </property>
+        </column>
+        <column>
+         <property name="text">
+          <string>TH (dB)</string>
+         </property>
+         <property name="toolTip">
+          <string>Frequency specific threshold in dB
+
+Leave blank to use common setting</string>
+         </property>
+        </column>
+        <column>
+         <property name="text">
+          <string>Sq (dB)</string>
+         </property>
+         <property name="toolTip">
+          <string>Frequency specific squelch in dB
+
+Leave blank for no adjustment</string>
+         </property>
+        </column>
        </widget>
       </item>
       <item>
@@ -783,18 +823,18 @@
    <extends>QToolButton</extends>
    <header>gui/buttonswitch.h</header>
   </customwidget>
-  <customwidget>
-   <class>RollupContents</class>
-   <extends>QWidget</extends>
-   <header>gui/rollupcontents.h</header>
-   <container>1</container>
-  </customwidget>
   <customwidget>
    <class>ValueDialZ</class>
    <extends>QWidget</extends>
    <header>gui/valuedialz.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>RollupContents</class>
+   <extends>QWidget</extends>
+   <header>gui/rollupcontents.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>deltaFrequency</tabstop>
diff --git a/plugins/channelrx/freqscanner/freqscannersettings.cpp b/plugins/channelrx/freqscanner/freqscannersettings.cpp
index 4d166040e..edc83c9ce 100644
--- a/plugins/channelrx/freqscanner/freqscannersettings.cpp
+++ b/plugins/channelrx/freqscanner/freqscannersettings.cpp
@@ -16,6 +16,7 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
 #include <QColor>
+#include <QDebug>
 
 #include "util/simpleserializer.h"
 #include "settings/serializable.h"
@@ -40,6 +41,7 @@ void FreqScannerSettings::resetToDefaults()
     m_channelFrequencyOffset = 25000;
     m_threshold = -60.0f;
     m_channel = "";
+    m_frequencySettings = {};
     m_scanTime = 0.1f;
     m_retransmitTime = 2.0f;
     m_tuneTime = 100;
@@ -73,9 +75,6 @@ QByteArray FreqScannerSettings::serialize() const
     s.writeS32(2, m_channelBandwidth);
     s.writeS32(3, m_channelFrequencyOffset);
     s.writeFloat(4, m_threshold);
-    s.writeList(5, m_notes);
-    s.writeList(6, m_enabled);
-    s.writeList(7, m_frequencies);
     s.writeString(8, m_channel);
     s.writeFloat(9, m_scanTime);
     s.writeFloat(10, m_retransmitTime);
@@ -83,6 +82,7 @@ QByteArray FreqScannerSettings::serialize() const
     s.writeS32(12, (int)m_priority);
     s.writeS32(13, (int)m_measurement);
     s.writeS32(14, (int)m_mode);
+    s.writeList(15, m_frequencySettings);
 
     s.writeList(20, m_columnIndexes);
     s.writeList(21, m_columnSizes);
@@ -128,22 +128,37 @@ bool FreqScannerSettings::deserialize(const QByteArray& data)
         d.readS32(2, &m_channelBandwidth, 25000);
         d.readS32(3, &m_channelFrequencyOffset, 25000);
         d.readFloat(4, &m_threshold, -60.0f);
-        d.readList(5, &m_notes);
-        d.readList(6, &m_enabled);
-        d.readList(7, &m_frequencies);
         d.readString(8, &m_channel);
-        while (m_notes.size() < m_frequencies.size()) {
-            m_notes.append("");
-        }
-        while (m_enabled.size() < m_frequencies.size()) {
-            m_enabled.append(true);
-        }
         d.readFloat(9, &m_scanTime, 0.1f);
         d.readFloat(10, &m_retransmitTime, 2.0f);
         d.readS32(11, &m_tuneTime, 100);
         d.readS32(12, (int*)&m_priority, (int)MAX_POWER);
         d.readS32(13, (int*)&m_measurement, (int)PEAK);
         d.readS32(14, (int*)&m_mode, (int)CONTINUOUS);
+        d.readList(15, &m_frequencySettings);
+        if (m_frequencySettings.size() == 0)
+        {
+            // Try reading old settings
+            QList<bool> enabled;
+            QList<qint64> frequencies;
+
+            d.readList(6, &enabled);
+            d.readList(7, &frequencies);
+            if (frequencies.size() > 0)
+            {
+                for (int i = 0; i < frequencies.size(); i++)
+                {
+                    FrequencySettings frequencySettings;
+                    frequencySettings.m_frequency = frequencies[i];
+                    if (i < enabled.size()) {
+                        frequencySettings.m_enabled = enabled[i];
+                    } else {
+                        frequencySettings.m_enabled = true;
+                    }
+                    m_frequencySettings.append(frequencySettings);
+                }
+            }
+        }
 
         d.readList(20, &m_columnIndexes);
         d.readList(21, &m_columnSizes);
@@ -200,10 +215,8 @@ void FreqScannerSettings::applySettings(const QStringList& settingsKeys, const F
     if (settingsKeys.contains("threshold")) {
         m_threshold = settings.m_threshold;
     }
-    if (settingsKeys.contains("frequencies")) {
-        m_frequencies = settings.m_frequencies;
-        m_enabled = settings.m_enabled;
-        m_notes = settings.m_notes;
+    if (settingsKeys.contains("frequencySettings")) {
+        m_frequencySettings = settings.m_frequencySettings;
     }
     if (settingsKeys.contains("channel")) {
         m_channel = settings.m_channel;
@@ -280,13 +293,13 @@ QString FreqScannerSettings::getDebugString(const QStringList& settingsKeys, boo
     if (settingsKeys.contains("threshold") || force) {
         ostr << " m_threshold: " << m_threshold;
     }
-    if (settingsKeys.contains("frequencies") || force)
+    if (settingsKeys.contains("frequencySettings") || force)
     {
         QStringList s;
-        for (auto f : m_frequencies) {
-            s.append(QString::number(f));
+        for (auto f : m_frequencySettings) {
+            s.append(QString::number(f.m_frequency));
         }
-        ostr << " m_frequencies: " << s.join(",").toStdString();
+        ostr << " m_frequencySettings: " << s.join(",").toStdString();
     }
     if (settingsKeys.contains("channel") || force) {
         ostr << " m_channel: " << m_channel.toStdString();
@@ -348,3 +361,105 @@ QString FreqScannerSettings::getDebugString(const QStringList& settingsKeys, boo
 
     return QString(ostr.str().c_str());
 }
+
+
+QByteArray FreqScannerSettings::FrequencySettings::serialize() const
+{
+    SimpleSerializer s(1);
+
+    s.writeS64(1, m_frequency);
+    s.writeBool(2, m_enabled);
+    s.writeString(3, m_notes);
+    s.writeString(4, m_threshold);
+    s.writeString(5, m_channel);
+    s.writeString(6, m_channelBandwidth);
+    s.writeString(7, m_squelch);
+
+    return s.final();
+}
+
+bool FreqScannerSettings::FrequencySettings::deserialize(const QByteArray& data)
+{
+    SimpleDeserializer d(data);
+
+    if (!d.isValid()) {
+        return false;
+    }
+
+    if (d.getVersion() == 1)
+    {
+        QByteArray blob;
+
+        d.readS64(1, &m_frequency);
+        d.readBool(2, &m_enabled);
+        d.readString(3, &m_notes);
+        d.readString(4, &m_threshold);
+        d.readString(5, &m_channel);
+        d.readString(6, &m_channelBandwidth);
+        d.readString(7, &m_squelch);
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+QDataStream& operator<<(QDataStream& out, const FreqScannerSettings::FrequencySettings& settings)
+{
+    out << settings.serialize();
+    return out;
+}
+
+QDataStream& operator>>(QDataStream& in, FreqScannerSettings::FrequencySettings& settings)
+{
+    QByteArray data;
+    in >> data;
+    settings.deserialize(data);
+    return in;
+}
+
+Real FreqScannerSettings::getThreshold(FreqScannerSettings::FrequencySettings *frequencySettings) const
+{
+    Real threshold = m_threshold;
+    if (!frequencySettings->m_threshold.isEmpty())
+    {
+        bool ok;
+        Real perFrequencyThreshold = frequencySettings->m_threshold.toFloat(&ok);
+        if (ok) {
+            threshold = perFrequencyThreshold;
+        } else {
+            qDebug() << "FreqScannerSettings::getThreshold: Failed to parse" << frequencySettings->m_threshold << "as a float";
+        }
+    }
+    return threshold;
+}
+
+int FreqScannerSettings::getChannelBandwidth(FreqScannerSettings::FrequencySettings *frequencySettings) const
+{
+    int channelBandwidth = m_channelBandwidth;
+    if (!frequencySettings->m_channelBandwidth.isEmpty())
+    {
+        bool ok;
+        Real perFrequencyChannelBandwidth = frequencySettings->m_channelBandwidth.toInt(&ok);
+        if (ok) {
+            channelBandwidth = perFrequencyChannelBandwidth;
+        } else {
+            qDebug() << "FreqScannerSettings::getChannelBandwidth: Failed to parse" << frequencySettings->m_channelBandwidth << "as an int";
+        }
+    }
+    return channelBandwidth;
+}
+
+FreqScannerSettings::FrequencySettings *FreqScannerSettings::getFrequencySettings(qint64 frequency)
+{
+    for (int i = 0; i < m_frequencySettings.size(); i++)
+    {
+        if (frequency == m_frequencySettings[i].m_frequency) {
+            return &this->m_frequencySettings[i];
+        }
+    }
+    return nullptr;
+}
+
diff --git a/plugins/channelrx/freqscanner/freqscannersettings.h b/plugins/channelrx/freqscanner/freqscannersettings.h
index c50e7a899..e07ba7b49 100644
--- a/plugins/channelrx/freqscanner/freqscannersettings.h
+++ b/plugins/channelrx/freqscanner/freqscannersettings.h
@@ -27,7 +27,7 @@ class Serializable;
 class ChannelAPI;
 
 // Number of columns in the table
-#define FREQSCANNER_COLUMNS           6
+#define FREQSCANNER_COLUMNS           10
 
 struct FreqScannerSettings
 {
@@ -41,14 +41,25 @@ struct FreqScannerSettings
         AvailableChannel& operator=(const AvailableChannel&) = default;
     };
 
+    struct FrequencySettings {
+        qint64 m_frequency;
+        bool m_enabled;
+        QString m_notes;
+        QString m_threshold;        // QStrings used, as we allow "" for no setting
+        QString m_channel;
+        QString m_channelBandwidth;
+        QString m_squelch;
+
+        QByteArray serialize() const;
+        bool deserialize(const QByteArray& data);
+    };
+
     qint32 m_inputFrequencyOffset;  //!< Not modifable in GUI
     qint32 m_channelBandwidth;      //!< Channel bandwidth
     qint32 m_channelFrequencyOffset;//!< Minium DC offset of tuned channel
     Real m_threshold;               //!< Power threshold in dB
-    QList<qint64> m_frequencies;    //!< Frequencies to scan
-    QList<bool> m_enabled;          //!< Whether corresponding frequency is enabled
-    QList<QString> m_notes;         //!< User editable notes about this frequency
     QString m_channel;              //!< Channel (E.g: R1:4) to tune to active frequency
+    QList<FrequencySettings> m_frequencySettings; //!< Frequencies to scan and corresponding settings
     float m_scanTime;               //!< In seconds
     float m_retransmitTime;         //!< In seconds
     int m_tuneTime;                 //!< In milliseconds
@@ -92,6 +103,9 @@ struct FreqScannerSettings
     bool deserialize(const QByteArray& data);
     void applySettings(const QStringList& settingsKeys, const FreqScannerSettings& settings);
     QString getDebugString(const QStringList& settingsKeys, bool force = false) const;
+    Real getThreshold(FreqScannerSettings::FrequencySettings *frequencySettings) const;
+    int getChannelBandwidth(FreqScannerSettings::FrequencySettings *frequencySettings) const;
+    FreqScannerSettings::FrequencySettings *getFrequencySettings(qint64 frequency);
 };
 
 #endif /* INCLUDE_FREQSCANNERSETTINGS_H */
diff --git a/plugins/channelrx/freqscanner/freqscannersink.cpp b/plugins/channelrx/freqscanner/freqscannersink.cpp
index a27c0b3cf..263b7b5e8 100644
--- a/plugins/channelrx/freqscanner/freqscannersink.cpp
+++ b/plugins/channelrx/freqscanner/freqscannersink.cpp
@@ -107,11 +107,11 @@ void FreqScannerSink::processOneSample(Complex &ci)
                 FreqScanner::MsgScanResult* msg = FreqScanner::MsgScanResult::create(m_fftStartTime);
                 QList<FreqScanner::MsgScanResult::ScanResult>& results = msg->getScanResults();
 
-                for (int i = 0; i < m_settings.m_frequencies.size(); i++)
+                for (int i = 0; i < m_settings.m_frequencySettings.size(); i++)
                 {
-                    if (m_settings.m_enabled[i])
+                    if (m_settings.m_frequencySettings[i].m_enabled)
                     {
-                        qint64 frequency = m_settings.m_frequencies[i];
+                        qint64 frequency = m_settings.m_frequencySettings[i].m_frequency;
                         qint64 startFrequency = m_centerFrequency - m_scannerSampleRate / 2;
                         qint64 diff = frequency - startFrequency;
                         float binBW = m_scannerSampleRate / (float)m_fftSize;
@@ -120,13 +120,24 @@ void FreqScannerSink::processOneSample(Complex &ci)
                         if ((diff < m_scannerSampleRate * 0.875f) && (diff >= m_scannerSampleRate * 0.125f))
                         {
                             int bin = std::round(diff / binBW);
+                            int channelBins;
+
+                            if (m_settings.m_frequencySettings[i].m_channelBandwidth.isEmpty())
+                            {
+                                channelBins = m_binsPerChannel;
+                            }
+                            else
+                            {
+                                int channelBW = m_settings.getChannelBandwidth(&m_settings.m_frequencySettings[i]);
+                                channelBins = m_fftSize / (m_scannerSampleRate / (float)channelBW);
+                            }
 
                             // Calculate power at that frequency
                             Real power;
                             if (m_settings.m_measurement == FreqScannerSettings::PEAK) {
-                                power = peakPower(bin);
+                                power = peakPower(bin, channelBins);
                             } else {
-                                power = totalPower(bin);
+                                power = totalPower(bin, channelBins);
                             }
                             //qDebug() << "startFrequency:" << startFrequency << "m_scannerSampleRate:" << m_scannerSampleRate << "m_centerFrequency:" << m_centerFrequency << "frequency" << frequency << "bin" << bin << "power" << power;
                             FreqScanner::MsgScanResult::ScanResult result = {frequency, power};
@@ -144,13 +155,13 @@ void FreqScannerSink::processOneSample(Complex &ci)
 }
 
 // Calculate total power in a channel containing the specified bin (i.e. sums adjacent bins in the same channel)
-Real FreqScannerSink::totalPower(int bin) const
+Real FreqScannerSink::totalPower(int bin, int channelBins) const
 {
     // Skip bin between halfway between channels
     // Then skip first and last bins, to avoid spectral leakage (particularly at DC)
-    int startBin = bin - m_binsPerChannel / 2 + 1 + 1;
+    int startBin = bin - channelBins / 2 + 1 + 1;
     Real magSqSum = 0.0f;
-    for (int i = 0; i < m_binsPerChannel - 2 - 1; i++) {
+    for (int i = 0; i < channelBins - 2 - 1; i++) {
         int idx = startBin + i;
         if ((idx < 0) || (idx >= m_fftSize)) {
             continue;
@@ -162,13 +173,13 @@ Real FreqScannerSink::totalPower(int bin) const
 }
 
 // Calculate peak power in a channel containing the specified bin
-Real FreqScannerSink::peakPower(int bin) const
+Real FreqScannerSink::peakPower(int bin, int channelBins) const
 {
     // Skip bin between halfway between channels
     // Then skip first and last bins, to avoid spectral leakage (particularly at DC)
-    int startBin = bin - m_binsPerChannel/2 + 1 + 1;
+    int startBin = bin - channelBins/2 + 1 + 1;
     Real maxMagSq = std::numeric_limits<Real>::min();
-    for (int i = 0; i < m_binsPerChannel - 2 - 1; i++)
+    for (int i = 0; i < channelBins - 2 - 1; i++)
     {
         int idx = startBin + i;
         if ((idx < 0) || (idx >= m_fftSize)) {
diff --git a/plugins/channelrx/freqscanner/freqscannersink.h b/plugins/channelrx/freqscanner/freqscannersink.h
index bea25bdea..2c84f0310 100644
--- a/plugins/channelrx/freqscanner/freqscannersink.h
+++ b/plugins/channelrx/freqscanner/freqscannersink.h
@@ -79,8 +79,8 @@ private:
 
     void processOneSample(Complex &ci);
     MessageQueue *getMessageQueueToChannel() { return m_messageQueueToChannel; }
-    Real totalPower(int bin) const;
-    Real peakPower(int bin) const;
+    Real totalPower(int bin, int channelBins) const;
+    Real peakPower(int bin, int channelBins) const;
     Real magSq(int bin) const;
 };
 
diff --git a/plugins/channelrx/freqscanner/readme.md b/plugins/channelrx/freqscanner/readme.md
index d5126484f..4995c09be 100644
--- a/plugins/channelrx/freqscanner/readme.md
+++ b/plugins/channelrx/freqscanner/readme.md
@@ -97,6 +97,10 @@ The frequency table contains the list of frequencies to be scanned, along with r
 - Power (dB): Displays the measured power in decibels from the last scan. The cell will have a green background if the power was above the threshold (4).
 - Active Count: Displays the number of scans in which the power for this frequency was above the threshold (4). This allows you to see which frequencies are commonly in use.
 - Notes: Available for user-entry of notes/information about this frequency.
+- Channel: Specifies the channel that should be tuned when this frequency is active. If blank, the common Channel setting (1) is used.
+- Ch Bw (Hz): Specifies the channel bandwidth in Hertz. If blank, the common Channel Bandwidth setting (8) is used.
+- TH (dB): Specifies the power threshold in dB that determines whether this frequency is active or not. If blank, the common Threshold setting (4) is used.
+- Sq (dB): Specifies a squelch level in dB that will be applied to the Channel when active. If blank, the squelch level will not be changed.
 
 When an active frequency is found after a scan, the corresponding row in the table will be selected.
 
diff --git a/sdrbase/channel/channelwebapiutils.cpp b/sdrbase/channel/channelwebapiutils.cpp
index 198102f50..a23e83a0f 100644
--- a/sdrbase/channel/channelwebapiutils.cpp
+++ b/sdrbase/channel/channelwebapiutils.cpp
@@ -1293,6 +1293,53 @@ bool ChannelWebAPIUtils::patchFeatureSetting(unsigned int featureSetIndex, unsig
     }
 }
 
+bool ChannelWebAPIUtils::patchChannelSetting(unsigned int deviceSetIndex, unsigned int channelIndex, const QString &setting, double value)
+{
+    SWGSDRangel::SWGChannelSettings channelSettingsResponse;
+    QString errorResponse;
+    int httpRC;
+    ChannelAPI *channel;
+
+    if (getChannelSettings(deviceSetIndex, channelIndex, channelSettingsResponse, channel))
+    {
+        // Patch settings
+        QJsonObject *jsonObj = channelSettingsResponse.asJsonObject();
+        double oldValue;
+        if (WebAPIUtils::getSubObjectDouble(*jsonObj, setting, oldValue))
+        {
+            WebAPIUtils::setSubObjectDouble(*jsonObj, setting, value);
+            QStringList channelSettingsKeys;
+            channelSettingsKeys.append(setting);
+            channelSettingsResponse.init();
+            channelSettingsResponse.fromJsonObject(*jsonObj);
+            SWGSDRangel::SWGErrorResponse errorResponse2;
+
+            httpRC = channel->webapiSettingsPutPatch(false, channelSettingsKeys, channelSettingsResponse, *errorResponse2.getMessage());
+
+            if (httpRC/100 == 2)
+            {
+                qDebug("ChannelWebAPIUtils::patchChannelSetting: set feature setting %s to %f OK", qPrintable(setting), value);
+                return true;
+            }
+            else
+            {
+                qWarning("ChannelWebAPIUtils::patchChannelSetting: set feature setting %s to %f error %d: %s",
+                    qPrintable(setting), value, httpRC, qPrintable(*errorResponse2.getMessage()));
+                return false;
+            }
+        }
+        else
+        {
+            qWarning("ChannelWebAPIUtils::patchChannelSetting: no key %s in feature settings", qPrintable(setting));
+            return false;
+        }
+    }
+    else
+    {
+        return false;
+    }
+}
+
 bool ChannelWebAPIUtils::patchChannelSetting(unsigned int deviceSetIndex, unsigned int channelIndex, const QString &setting, const QJsonArray& value)
 {
     SWGSDRangel::SWGChannelSettings channelSettingsResponse;
diff --git a/sdrbase/channel/channelwebapiutils.h b/sdrbase/channel/channelwebapiutils.h
index 79a959e15..1552c2c44 100644
--- a/sdrbase/channel/channelwebapiutils.h
+++ b/sdrbase/channel/channelwebapiutils.h
@@ -73,6 +73,7 @@ public:
     static bool patchDeviceSetting(unsigned int deviceIndex, const QString &setting, int value);
     static bool patchFeatureSetting(unsigned int featureSetIndex, unsigned int featureIndex, const QString &setting, const QString &value);
     static bool patchFeatureSetting(unsigned int featureSetIndex, unsigned int featureIndex, const QString &setting, double value);
+    static bool patchChannelSetting(unsigned int deviceSetIndex, unsigned int channeIndex, const QString &setting, double value);
     static bool patchChannelSetting(unsigned int deviceSetIndex, unsigned int channeIndex, const QString &setting, const QJsonArray& value);
     static bool getFeatureSetting(unsigned int featureSetIndex, unsigned int featureIndex, const QString &setting, int &value);
     static bool getFeatureSetting(unsigned int featureSetIndex, unsigned int featureIndex, const QString &setting, double &value);
diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html
index 602af01fc..a03a604b1 100644
--- a/sdrbase/resources/webapi/doc/html2/index.html
+++ b/sdrbase/resources/webapi/doc/html2/index.html
@@ -7007,6 +7007,18 @@ margin-bottom: 20px;
     },
     "notes" : {
       "type" : "string"
+    },
+    "channel" : {
+      "type" : "string"
+    },
+    "channelBandwidth" : {
+      "type" : "string"
+    },
+    "threshold" : {
+      "type" : "string"
+    },
+    "squelch" : {
+      "type" : "string"
     }
   }
 };
@@ -58401,7 +58413,7 @@ except ApiException as e:
           </div>
           <div id="generator">
             <div class="content">
-              Generated 2023-11-05T10:45:45.965+01:00
+              Generated 2023-11-30T13:04:24.913+01:00
             </div>
           </div>
       </div>
diff --git a/sdrbase/resources/webapi/doc/swagger/include/FreqScanner.yaml b/sdrbase/resources/webapi/doc/swagger/include/FreqScanner.yaml
index 866c118f3..64e74ffef 100644
--- a/sdrbase/resources/webapi/doc/swagger/include/FreqScanner.yaml
+++ b/sdrbase/resources/webapi/doc/swagger/include/FreqScanner.yaml
@@ -69,3 +69,11 @@ FreqScannerFrequency:
       type: integer
     notes:
       type: string
+    channel:
+      type: string
+    channelBandwidth:
+      type: string
+    threshold:
+      type: string
+    squelch:
+      type: string
diff --git a/sdrbase/util/simpleserializer.h b/sdrbase/util/simpleserializer.h
index a25cb949c..de152c330 100644
--- a/sdrbase/util/simpleserializer.h
+++ b/sdrbase/util/simpleserializer.h
@@ -105,7 +105,7 @@ public:
 	bool readBlob(quint32 id, QByteArray* result, const QByteArray& def = QByteArray()) const;
 
 	template<typename T>
-	bool readList(quint32 id, QList<T>* result)
+	bool readList(quint32 id, QList<T>* result, const QList<T>& def = {})
 	{
 		QByteArray data;
 		bool ok = readBlob(id, &data);
@@ -115,10 +115,14 @@ public:
 			(*stream) >> *result;
 			delete stream;
 		}
+		else
+		{
+			*result = def;
+		}
 		return ok;
 	}
 	template<typename TK, typename TV>
-	bool readHash(quint32 id, QHash<TK,TV>* result)
+	bool readHash(quint32 id, QHash<TK,TV>* result, const QHash<TK,TV>& def = {})
 	{
 		QByteArray data;
 		bool ok = readBlob(id, &data);
@@ -128,6 +132,10 @@ public:
 			(*stream) >> *result;
 			delete stream;
 		}
+		else
+		{
+			*result = def;
+		}
 		return ok;
 	}
 
diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt
index 0770ec523..358e4029f 100644
--- a/sdrgui/CMakeLists.txt
+++ b/sdrgui/CMakeLists.txt
@@ -63,6 +63,8 @@ set(sdrgui_SOURCES
     gui/graphicsviewzoom.cpp
     gui/httpdownloadmanagergui.cpp
     gui/indicator.cpp
+    gui/int64delegate.cpp
+    gui/int64validator.cpp
     gui/levelmeter.cpp
     gui/loggingdialog.cpp
     gui/logslider.cpp
@@ -186,6 +188,8 @@ set(sdrgui_HEADERS
     gui/graphicsviewzoom.h
     gui/httpdownloadmanagergui.h
     gui/indicator.h
+    gui/int64delegate.h
+    gui/int64validator.h
     gui/levelmeter.h
     gui/loggingdialog.h
     gui/logslider.h
diff --git a/sdrgui/gui/decimaldelegate.cpp b/sdrgui/gui/decimaldelegate.cpp
index 3cfe533b4..2b56b74cd 100644
--- a/sdrgui/gui/decimaldelegate.cpp
+++ b/sdrgui/gui/decimaldelegate.cpp
@@ -18,10 +18,40 @@
 // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 ///////////////////////////////////////////////////////////////////////////////////
 
+#include <QLineEdit>
+#include <QDoubleValidator>
+
 #include "decimaldelegate.h"
 
+// Allow "" or double
+class DoubleOrEmptyValidator : public QDoubleValidator {
+public:
+    DoubleOrEmptyValidator(double bottom, double top, int decimals, QObject *parent = nullptr) :
+        QDoubleValidator(bottom, top, decimals, parent)
+    {
+    }
+
+    QValidator::State validate(QString& input, int &pos) const
+    {
+        if (input == "") {
+            return QValidator::Acceptable;
+        } else {
+            return QDoubleValidator::validate(input, pos);
+        }
+    }
+};
+
 DecimalDelegate::DecimalDelegate(int precision) :
-    m_precision(precision)
+    m_precision(precision),
+    m_min(-std::numeric_limits<double>::max()),
+    m_max(std::numeric_limits<double>::max())
+{
+}
+
+DecimalDelegate::DecimalDelegate(int precision, double min, double max) :
+    m_precision(precision),
+    m_min(min),
+    m_max(max)
 {
 }
 
@@ -36,3 +66,22 @@ QString DecimalDelegate::displayText(const QVariant &value, const QLocale &local
         return value.toString();
     }
 }
+
+QWidget *DecimalDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    (void) option;
+    (void) index;
+
+    QLineEdit* editor = new QLineEdit(parent);
+    DoubleOrEmptyValidator *validator = new DoubleOrEmptyValidator(m_min, m_max, m_precision);
+    validator->setBottom(m_min);
+    validator->setTop(m_max);
+    editor->setValidator(validator);
+    return editor;
+}
+
+void DecimalDelegate::setRange(double min, double max)
+{
+    m_min = min;
+    m_max = max;
+}
diff --git a/sdrgui/gui/decimaldelegate.h b/sdrgui/gui/decimaldelegate.h
index 9fb2dce71..a88ec4dad 100644
--- a/sdrgui/gui/decimaldelegate.h
+++ b/sdrgui/gui/decimaldelegate.h
@@ -26,17 +26,23 @@
 #include "export.h"
 
 // Deligate for table to control precision used to display floating point values - also supports strings
+// Min and max values are constraints for editing
 class SDRGUI_API DecimalDelegate : public QStyledItemDelegate {
 
 public:
     DecimalDelegate(int precision = 2);
+    DecimalDelegate(int precision, double min, double max);
 
     virtual QString displayText(const QVariant &value, const QLocale &locale) const override;
+    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
     int getPrecision() const { return m_precision; }
     void setPrecision(int precision) { m_precision = precision; }
+    void setRange(double min, double max);
 
 private:
     int m_precision;
+    double m_min;
+    double m_max;
 
 };
 
diff --git a/sdrgui/gui/frequencydelegate.cpp b/sdrgui/gui/frequencydelegate.cpp
index da01c1093..057f5d3a4 100644
--- a/sdrgui/gui/frequencydelegate.cpp
+++ b/sdrgui/gui/frequencydelegate.cpp
@@ -21,6 +21,7 @@
 #include <QLineEdit>
 
 #include "frequencydelegate.h"
+#include "int64validator.h"
 
 FrequencyDelegate::FrequencyDelegate(const QString& units, int precision, bool group) :
     m_units(units),
@@ -112,13 +113,14 @@ QString FrequencyDelegate::displayText(const QVariant &value, const QLocale &loc
     }
 }
 
+
 QWidget* FrequencyDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
 {
     (void) option;
     (void) index;
 
     QLineEdit* editor = new QLineEdit(parent);
-    QIntValidator* validator = new QIntValidator();
+    Int64Validator* validator = new Int64Validator();
     validator->setBottom(0);
     editor->setValidator(validator);
     return editor;
diff --git a/sdrgui/gui/int64delegate.cpp b/sdrgui/gui/int64delegate.cpp
new file mode 100644
index 000000000..c5a8e7781
--- /dev/null
+++ b/sdrgui/gui/int64delegate.cpp
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2023 Jon Beniston, M7RCE <jon@beniston.com>                     //
+//                                                                               //
+// 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 <QLineEdit>
+
+#include "int64delegate.h"
+#include "int64validator.h"
+
+Int64Delegate::Int64Delegate() :
+    m_min(-std::numeric_limits<qint64>::max()),
+    m_max(std::numeric_limits<qint64>::max())
+{
+}
+
+Int64Delegate::Int64Delegate(qint64 min, qint64 max) :
+    m_min(min),
+    m_max(max)
+{
+}
+
+QString Int64Delegate::displayText(const QVariant &value, const QLocale &locale) const
+{
+    (void) locale;
+
+    return value.toString();
+}
+
+QWidget *Int64Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    (void) option;
+    (void) index;
+
+    QLineEdit* editor = new QLineEdit(parent);
+    Int64Validator* validator = new Int64Validator();
+    validator->setBottom(m_min);
+    validator->setTop(m_max);
+    editor->setValidator(validator);
+    return editor;
+}
+
+void Int64Delegate::setRange(qint64 min, qint64 max)
+{
+    m_min = min;
+    m_max = max;
+}
diff --git a/sdrgui/gui/int64delegate.h b/sdrgui/gui/int64delegate.h
new file mode 100644
index 000000000..e69688f07
--- /dev/null
+++ b/sdrgui/gui/int64delegate.h
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2023 Jon Beniston, M7RCE <jon@beniston.com>                     //
+//                                                                               //
+// 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 SDRGUI_GUI_INT64DELGATE_H
+#define SDRGUI_GUI_INT64DELGATE_H
+
+#include <QStyledItemDelegate>
+
+#include "export.h"
+
+// Delegate for table to display a qint64 with input range validation
+// Also supports "" as a value
+class SDRGUI_API Int64Delegate : public QStyledItemDelegate {
+
+public:
+    Int64Delegate();
+    Int64Delegate(qint64 min, qint64 max);
+    virtual QString displayText(const QVariant &value, const QLocale &locale) const override;
+    virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+    void setMin(qint64 min) { m_min = min; }
+    void setMax(qint64 max) { m_max = max; }
+    void setRange(qint64 min, qint64 max);
+    qint64 min() const { return m_min; }
+    qint64 max() const { return m_max; }
+
+private:
+    qint64 m_min;
+    qint64 m_max;
+
+};
+
+#endif // SDRGUI_GUI_INT64DELGATE_H
diff --git a/sdrgui/gui/int64validator.cpp b/sdrgui/gui/int64validator.cpp
new file mode 100644
index 000000000..09d2863dc
--- /dev/null
+++ b/sdrgui/gui/int64validator.cpp
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2023 Jon Beniston, M7RCE <jon@beniston.com>                     //
+//                                                                               //
+// 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 "int64validator.h"
+
+QValidator::State Int64Validator::validate(QString& input, int &pos) const
+{
+    if (input == "") {
+        return QValidator::Acceptable;
+    }
+
+    if ((m_bottom < 0) && (input == "-")) {
+        return QValidator::Intermediate;
+    }
+
+    QRegularExpression re("-?\\d+");
+    QRegularExpressionMatch match = re.match(input);
+    if (match.hasMatch())
+    {
+        qint64 value = input.toLongLong();
+        if (value < m_bottom) {
+            return QValidator::Invalid;
+        }
+        if (value > m_top) {
+            return QValidator::Invalid;
+        }
+        return QValidator::Acceptable;
+    }
+    else
+    {
+        return QValidator::Invalid;
+    }
+}
diff --git a/sdrgui/gui/int64validator.h b/sdrgui/gui/int64validator.h
new file mode 100644
index 000000000..7a8866392
--- /dev/null
+++ b/sdrgui/gui/int64validator.h
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2023 Jon Beniston, M7RCE <jon@beniston.com>                     //
+//                                                                               //
+// 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 <limits>
+
+#include <QValidator>
+#include <QRegularExpression>
+
+// Like QIntValidator but for qint64
+class Int64Validator : public QValidator
+{
+    Q_OBJECT
+
+public:
+
+    Int64Validator(QObject *parent = nullptr) :
+        QValidator(parent),
+        m_bottom(-std::numeric_limits<qint64>::max()),
+        m_top(std::numeric_limits<qint64>::max())
+    {
+    }
+
+    Int64Validator(qint64 bottom, qint64 top, QObject *parent = nullptr) :
+        QValidator(parent),
+        m_bottom(bottom),
+        m_top(top)
+    {
+    }
+
+    void setBottom(qint64 bottom)
+    {
+        m_bottom = bottom;
+    }
+
+    void setTop(qint64 top)
+    {
+        m_top = top;
+    }
+
+    void setRange(qint64 bottom, qint64 top)
+    {
+        m_bottom = bottom;
+        m_top = top;
+    }
+
+    qint64 bottom() const
+    {
+        return m_bottom;
+    }
+
+    qint64 top() const
+    {
+        return m_top;
+    }
+
+    QValidator::State validate(QString& input, int &pos) const;
+
+private:
+    qint64 m_bottom;
+    qint64 m_top;
+};
diff --git a/swagger/sdrangel/api/swagger/include/FreqScanner.yaml b/swagger/sdrangel/api/swagger/include/FreqScanner.yaml
index d2bb0c510..3319faa68 100644
--- a/swagger/sdrangel/api/swagger/include/FreqScanner.yaml
+++ b/swagger/sdrangel/api/swagger/include/FreqScanner.yaml
@@ -69,3 +69,11 @@ FreqScannerFrequency:
       type: integer
     notes:
       type: string
+    channel:
+      type: string
+    channelBandwidth:
+      type: string
+    threshold:
+      type: string
+    squelch:
+      type: string
diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html
index 602af01fc..a03a604b1 100644
--- a/swagger/sdrangel/code/html2/index.html
+++ b/swagger/sdrangel/code/html2/index.html
@@ -7007,6 +7007,18 @@ margin-bottom: 20px;
     },
     "notes" : {
       "type" : "string"
+    },
+    "channel" : {
+      "type" : "string"
+    },
+    "channelBandwidth" : {
+      "type" : "string"
+    },
+    "threshold" : {
+      "type" : "string"
+    },
+    "squelch" : {
+      "type" : "string"
     }
   }
 };
@@ -58401,7 +58413,7 @@ except ApiException as e:
           </div>
           <div id="generator">
             <div class="content">
-              Generated 2023-11-05T10:45:45.965+01:00
+              Generated 2023-11-30T13:04:24.913+01:00
             </div>
           </div>
       </div>
diff --git a/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.cpp b/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.cpp
index f3d75133e..ba309ed06 100644
--- a/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.cpp
+++ b/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.cpp
@@ -34,6 +34,14 @@ SWGFreqScannerFrequency::SWGFreqScannerFrequency() {
     m_enabled_isSet = false;
     notes = nullptr;
     m_notes_isSet = false;
+    channel = nullptr;
+    m_channel_isSet = false;
+    channel_bandwidth = nullptr;
+    m_channel_bandwidth_isSet = false;
+    threshold = nullptr;
+    m_threshold_isSet = false;
+    squelch = nullptr;
+    m_squelch_isSet = false;
 }
 
 SWGFreqScannerFrequency::~SWGFreqScannerFrequency() {
@@ -48,6 +56,14 @@ SWGFreqScannerFrequency::init() {
     m_enabled_isSet = false;
     notes = new QString("");
     m_notes_isSet = false;
+    channel = new QString("");
+    m_channel_isSet = false;
+    channel_bandwidth = new QString("");
+    m_channel_bandwidth_isSet = false;
+    threshold = new QString("");
+    m_threshold_isSet = false;
+    squelch = new QString("");
+    m_squelch_isSet = false;
 }
 
 void
@@ -57,6 +73,18 @@ SWGFreqScannerFrequency::cleanup() {
     if(notes != nullptr) { 
         delete notes;
     }
+    if(channel != nullptr) { 
+        delete channel;
+    }
+    if(channel_bandwidth != nullptr) { 
+        delete channel_bandwidth;
+    }
+    if(threshold != nullptr) { 
+        delete threshold;
+    }
+    if(squelch != nullptr) { 
+        delete squelch;
+    }
 }
 
 SWGFreqScannerFrequency*
@@ -76,6 +104,14 @@ SWGFreqScannerFrequency::fromJsonObject(QJsonObject &pJson) {
     
     ::SWGSDRangel::setValue(&notes, pJson["notes"], "QString", "QString");
     
+    ::SWGSDRangel::setValue(&channel, pJson["channel"], "QString", "QString");
+    
+    ::SWGSDRangel::setValue(&channel_bandwidth, pJson["channelBandwidth"], "QString", "QString");
+    
+    ::SWGSDRangel::setValue(&threshold, pJson["threshold"], "QString", "QString");
+    
+    ::SWGSDRangel::setValue(&squelch, pJson["squelch"], "QString", "QString");
+    
 }
 
 QString
@@ -101,6 +137,18 @@ SWGFreqScannerFrequency::asJsonObject() {
     if(notes != nullptr && *notes != QString("")){
         toJsonValue(QString("notes"), notes, obj, QString("QString"));
     }
+    if(channel != nullptr && *channel != QString("")){
+        toJsonValue(QString("channel"), channel, obj, QString("QString"));
+    }
+    if(channel_bandwidth != nullptr && *channel_bandwidth != QString("")){
+        toJsonValue(QString("channelBandwidth"), channel_bandwidth, obj, QString("QString"));
+    }
+    if(threshold != nullptr && *threshold != QString("")){
+        toJsonValue(QString("threshold"), threshold, obj, QString("QString"));
+    }
+    if(squelch != nullptr && *squelch != QString("")){
+        toJsonValue(QString("squelch"), squelch, obj, QString("QString"));
+    }
 
     return obj;
 }
@@ -135,6 +183,46 @@ SWGFreqScannerFrequency::setNotes(QString* notes) {
     this->m_notes_isSet = true;
 }
 
+QString*
+SWGFreqScannerFrequency::getChannel() {
+    return channel;
+}
+void
+SWGFreqScannerFrequency::setChannel(QString* channel) {
+    this->channel = channel;
+    this->m_channel_isSet = true;
+}
+
+QString*
+SWGFreqScannerFrequency::getChannelBandwidth() {
+    return channel_bandwidth;
+}
+void
+SWGFreqScannerFrequency::setChannelBandwidth(QString* channel_bandwidth) {
+    this->channel_bandwidth = channel_bandwidth;
+    this->m_channel_bandwidth_isSet = true;
+}
+
+QString*
+SWGFreqScannerFrequency::getThreshold() {
+    return threshold;
+}
+void
+SWGFreqScannerFrequency::setThreshold(QString* threshold) {
+    this->threshold = threshold;
+    this->m_threshold_isSet = true;
+}
+
+QString*
+SWGFreqScannerFrequency::getSquelch() {
+    return squelch;
+}
+void
+SWGFreqScannerFrequency::setSquelch(QString* squelch) {
+    this->squelch = squelch;
+    this->m_squelch_isSet = true;
+}
+
 
 bool
 SWGFreqScannerFrequency::isSet(){
@@ -149,6 +237,18 @@ SWGFreqScannerFrequency::isSet(){
         if(notes && *notes != QString("")){
             isObjectUpdated = true; break;
         }
+        if(channel && *channel != QString("")){
+            isObjectUpdated = true; break;
+        }
+        if(channel_bandwidth && *channel_bandwidth != QString("")){
+            isObjectUpdated = true; break;
+        }
+        if(threshold && *threshold != QString("")){
+            isObjectUpdated = true; break;
+        }
+        if(squelch && *squelch != QString("")){
+            isObjectUpdated = true; break;
+        }
     }while(false);
     return isObjectUpdated;
 }
diff --git a/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.h b/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.h
index 996480723..1f2fd406b 100644
--- a/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.h
+++ b/swagger/sdrangel/code/qt5/client/SWGFreqScannerFrequency.h
@@ -51,6 +51,18 @@ public:
     QString* getNotes();
     void setNotes(QString* notes);
 
+    QString* getChannel();
+    void setChannel(QString* channel);
+
+    QString* getChannelBandwidth();
+    void setChannelBandwidth(QString* channel_bandwidth);
+
+    QString* getThreshold();
+    void setThreshold(QString* threshold);
+
+    QString* getSquelch();
+    void setSquelch(QString* squelch);
+
 
     virtual bool isSet() override;
 
@@ -64,6 +76,18 @@ private:
     QString* notes;
     bool m_notes_isSet;
 
+    QString* channel;
+    bool m_channel_isSet;
+
+    QString* channel_bandwidth;
+    bool m_channel_bandwidth_isSet;
+
+    QString* threshold;
+    bool m_threshold_isSet;
+
+    QString* squelch;
+    bool m_squelch_isSet;
+
 };
 
 }