Use full bandwidth

pull/1852/head
srcejon 2023-10-03 16:09:54 +01:00
rodzic d2526cdc5b
commit 83ceae4ba3
8 zmienionych plików z 64 dodań i 30 usunięć

Wyświetl plik

@ -44,6 +44,7 @@
#include "util/db.h"
#include "channel/channelwebapiutils.h"
#include "maincore.h"
#include "dsp/spectrumvis.h"
MESSAGE_CLASS_DEFINITION(FreqScanner::MsgConfigureFreqScanner, Message)
MESSAGE_CLASS_DEFINITION(FreqScanner::MsgReportChannels, Message)
@ -337,7 +338,7 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
// Calculate how many channels can be scanned in one go
int fftSize;
int binsPerChannel;
FreqScanner::calcScannerSampleRate(m_settings.m_channelBandwidth, m_basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel);
calcScannerSampleRate(m_settings.m_channelBandwidth, m_basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel);
// Align first frequency so we cover as many channels as possible, while avoiding DC bin
m_stepStartFrequency = frequencies.front() + m_scannerSampleRate / 2 - m_settings.m_channelBandwidth + m_settings.m_channelBandwidth / 2;
@ -351,6 +352,8 @@ void FreqScanner::processScanResults(const QDateTime& fftStartTime, const QList<
int spareChannelsEachSide = spareBWEachSide / m_settings.m_channelBandwidth;
int offset = spareChannelsEachSide * m_settings.m_channelBandwidth;
m_stepStartFrequency -= offset;
qDebug() << "*********** Starting scan: m_stepStartFrequency:" << m_stepStartFrequency << "offset:" << offset;
}
initScan();
@ -582,6 +585,32 @@ void FreqScanner::timeout()
initScan();
}
void FreqScanner::calcScannerSampleRate(int channelBW, int basebandSampleRate, int& scannerSampleRate, int& fftSize, int& binsPerChannel)
{
const int maxFFTSize = 16384;
const int minBinsPerChannel = 8;
// Base FFT size on that used for main spectrum
std::vector<DeviceSet*>& deviceSets = MainCore::instance()->getDeviceSets();
DeviceSet* deviceSet = deviceSets[m_deviceAPI->getDeviceSetIndex()];
const SpectrumSettings& spectrumSettings = deviceSet->m_spectrumVis->getSettings();
fftSize = spectrumSettings.m_fftSize;
// But ensure we have several bins per channel
// Adjust sample rate, to ensure we don't get massive FFT size
scannerSampleRate = basebandSampleRate;
while (fftSize / (scannerSampleRate / channelBW) < minBinsPerChannel)
{
if (fftSize == maxFFTSize) {
scannerSampleRate /= 2;
} else {
fftSize *= 2;
}
}
binsPerChannel = fftSize / (scannerSampleRate / (float)channelBW);
}
void FreqScanner::setCenterFrequency(qint64 frequency)
{
FreqScannerSettings settings = m_settings;
@ -647,6 +676,7 @@ void FreqScanner::applySettings(const FreqScannerSettings& settings, const QStri
|| settingsKeys.contains("priority")
|| settingsKeys.contains("measurement")
|| settingsKeys.contains("mode")
|| settingsKeys.contains("channelBandwidth")
|| force)
{
// Restart scan if any settings change

Wyświetl plik

@ -348,23 +348,7 @@ public:
uint32_t getNumberOfDeviceStreams() const;
static void calcScannerSampleRate(int channelBW, int basebandSampleRate, int& scannerSampleRate, int& fftSize, int& binsPerChannel)
{
const int maxFFTSize = 2048;
const int maxBinsPerChannel = 32;
const int minBinsPerChannel = 8;
// Use multiple bins per channel, to account for FFT spectral leakage
binsPerChannel = maxFFTSize / (basebandSampleRate / channelBW);
binsPerChannel = std::min(binsPerChannel, maxBinsPerChannel);
binsPerChannel = std::max(binsPerChannel, minBinsPerChannel);
double binBW = channelBW / (double)binsPerChannel;
// Find next smallest power of 2
fftSize = pow(2.0, floor(log2(basebandSampleRate / binBW)));
fftSize = std::min(maxFFTSize, fftSize);
scannerSampleRate = binBW * fftSize;
}
void calcScannerSampleRate(int channelBW, int basebandSampleRate, int& scannerSampleRate, int& fftSize, int& binsPerChannel);
static const char * const m_channelIdURI;
static const char * const m_channelId;

Wyświetl plik

@ -28,6 +28,7 @@
MESSAGE_CLASS_DEFINITION(FreqScannerBaseband::MsgConfigureFreqScannerBaseband, Message)
FreqScannerBaseband::FreqScannerBaseband(FreqScanner *freqScanner) :
m_freqScanner(freqScanner),
m_sink(freqScanner),
m_messageQueueToGUI(nullptr)
{
@ -147,7 +148,7 @@ bool FreqScannerBaseband::handleMessage(const Message& cmd)
void FreqScannerBaseband::applySettings(const FreqScannerSettings& settings, const QStringList& settingsKeys, bool force)
{
if ((settings.m_channelBandwidth != m_settings.m_channelBandwidth) || (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
if (settingsKeys.contains("channelBandwidth") || settingsKeys.contains("inputFrequencyOffset") || force)
{
int basebandSampleRate = m_channelizer->getBasebandSampleRate();
if ((basebandSampleRate != 0) && (settings.m_channelBandwidth != 0)) {
@ -182,7 +183,7 @@ void FreqScannerBaseband::calcScannerSampleRate(int basebandSampleRate, float rf
int fftSize;
int binsPerChannel;
FreqScanner::calcScannerSampleRate(rfBandwidth, basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel);
m_freqScanner->calcScannerSampleRate(rfBandwidth, basebandSampleRate, m_scannerSampleRate, fftSize, binsPerChannel);
m_channelizer->setChannelization(m_scannerSampleRate, inputFrequencyOffset);
m_channelSampleRate = m_channelizer->getChannelSampleRate();

Wyświetl plik

@ -75,6 +75,7 @@ public:
void setFifoLabel(const QString& label) { m_sampleFifo.setLabel(label); }
private:
FreqScanner *m_freqScanner;
SampleSinkFifo m_sampleFifo;
DownChannelizer *m_channelizer;
int m_channelSampleRate;

Wyświetl plik

@ -103,7 +103,7 @@ bool FreqScannerGUI::handleMessage(const Message& message)
m_basebandSampleRate = notif.getSampleRate();
ui->deltaFrequency->setValueRange(true, 7, 0, m_basebandSampleRate/2);
ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2));
ui->channelBandwidth->setValueRange(true, 7, 8, m_basebandSampleRate);
ui->channelBandwidth->setValueRange(true, 7, 0, m_basebandSampleRate);
if (m_channelMarker.getBandwidth() == 0) {
m_channelMarker.setBandwidth(m_basebandSampleRate);
}
@ -164,6 +164,7 @@ bool FreqScannerGUI::handleMessage(const Message& message)
FreqScanner::MsgReportScanRange& report = (FreqScanner::MsgReportScanRange&)message;
m_channelMarker.setCenterFrequency(report.getCenterFrequency());
m_channelMarker.setBandwidth(report.getTotalBandwidth());
m_channelMarker.setVisible(report.getTotalBandwidth() < m_basebandSampleRate); // Hide marker if full bandwidth
return true;
}
else if (FreqScanner::MsgScanResult::match(message))
@ -417,7 +418,7 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
m_channelMarker.setTitle("Frequency Scanner");
m_channelMarker.blockSignals(false);
m_channelMarker.setVisible(true); // activate signal on the last setting only
m_channelMarker.setVisible(true);
setTitleColor(m_channelMarker.getColor());
m_settings.setChannelMarker(&m_channelMarker);
@ -459,6 +460,8 @@ FreqScannerGUI::FreqScannerGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
ui->table->setItemDelegateForColumn(COL_FREQUENCY, new FrequencyDelegate("Auto", 3));
ui->table->setItemDelegateForColumn(COL_POWER, new DecimalDelegate(1));
connect(m_deviceUISet->m_spectrum->getSpectrumView(), &GLSpectrumView::updateAnnotations, this, &FreqScannerGUI::updateAnnotations);
}
FreqScannerGUI::~FreqScannerGUI()
@ -784,9 +787,13 @@ void FreqScannerGUI::updateAnnotation(int row)
// Exact match
annotationItem->setText(marker.m_text);
return;
} else if (!closest) {
}
else if (!closest)
{
closest = &marker;
} else {
}
else
{
if (marker.m_bandwidth < closest->m_bandwidth) {
closest = &marker;
}
@ -799,6 +806,13 @@ void FreqScannerGUI::updateAnnotation(int row)
}
}
void FreqScannerGUI::updateAnnotations()
{
for (int i = 0; i < ui->table->rowCount(); i++) {
updateAnnotation(i);
}
}
void FreqScannerGUI::table_customContextMenuRequested(QPoint pos)
{
QTableWidgetItem* item = ui->table->itemAt(pos);
@ -927,7 +941,7 @@ void FreqScannerGUI::resizeTable()
int row = ui->table->rowCount();
ui->table->setRowCount(row + 1);
ui->table->setItem(row, COL_FREQUENCY, new QTableWidgetItem("800,000.5 MHz"));
ui->table->setItem(row, COL_ANNOTATION, new QTableWidgetItem("An annotation"));
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_ACTIVE_COUNT, new QTableWidgetItem("10000"));

Wyświetl plik

@ -94,6 +94,7 @@ private:
void updateAbsoluteCenterFrequency();
void addRow(qint64 frequency, bool enabled, const QString& notes = "");
void updateAnnotation(int row);
void updateAnnotations();
void updateChannelsList(const QList<FreqScannerSettings::AvailableChannel>& channels);
void leaveEvent(QEvent*);

Wyświetl plik

@ -107,7 +107,7 @@ void FreqScannerSink::processOneSample(Complex &ci)
if (m_fftAverage.nextAverage())
{
// Send results to channel
if (getMessageQueueToChannel())
if (getMessageQueueToChannel() && (m_settings.m_channelBandwidth != 0) && (m_binsPerChannel != 0))
{
FreqScanner::MsgScanResult* msg = FreqScanner::MsgScanResult::create(m_fftStartTime);
QList<FreqScanner::MsgScanResult::ScanResult>& results = msg->getScanResults();
@ -119,11 +119,11 @@ void FreqScannerSink::processOneSample(Complex &ci)
qint64 frequency = m_settings.m_frequencies[i];
qint64 startFrequency = m_centerFrequency - m_scannerSampleRate / 2;
qint64 diff = frequency - startFrequency;
int binBW = m_settings.m_channelBandwidth / m_binsPerChannel;
float binBW = m_scannerSampleRate / (float)m_fftSize;
if ((diff < m_scannerSampleRate) && (diff >= 0))
{
int bin = diff / binBW;
int bin = std::round(diff / binBW);
// Calculate power at that frequency
Real power;
@ -132,7 +132,7 @@ void FreqScannerSink::processOneSample(Complex &ci)
} else {
power = totalPower(bin);
}
//qDebug() << "startFrequency:" << startFrequency << "m_scannerSampleRate:" << m_scannerSampleRate << "m_centerFrequency:" << m_centerFrequency << "frequency" << frequency << "bin" << bin << "power" << power;
FreqScanner::MsgScanResult::ScanResult result = {frequency, power};
results.append(result);
}
@ -177,6 +177,7 @@ Real FreqScannerSink::peakPower(int bin) const
if ((idx < 0) || (idx >= m_fftSize)) {
continue;
}
//qDebug() << "idx:" << idx << "power:" << CalcDb::dbPower(m_magSq[idx]);
maxMagSq = std::max(maxMagSq, m_magSq[idx]);
}
Real db = CalcDb::dbPower(maxMagSq);

Wyświetl plik

@ -56,7 +56,9 @@ Specifies which frequency will be chosen as the active frequency, when multiple
<h3>10: Meas - Power Measurement</h3>
Specifies how power is measured. In both cases, a FFT is used, with the channel bandwidth being spread over 8 to 32 bins, with the first and last bins being excluded from the measurement (to reduce spectral leakage from adjacent channels):
Specifies how power is measured. In both cases, a FFT is used.
FFT size is typically the same as used for the Main Spectrum, but may be increased to ensure at least 8 bins cover the channel bandwidth (8).
The first and last bins are excluded from the measurement (to reduce spectral leakage from adjacent channels):
- Peak: Power is the highest value in all of the bins, averaged over the scan time (6).
- Total: Power is the sum of power in all of the bins, averaged over the scan time (6).