Added software filter to waterfall controls to allow for a way to skip decoding signals outside of the filter range. Useful in a crowded band to prevent decodes from polluting your RX window

This commit is contained in:
Jordan Sherer 2019-12-16 13:42:44 -05:00
parent 24f1c5f343
commit bf5570cacd
8 changed files with 425 additions and 272 deletions

View File

@ -84,19 +84,18 @@ extern struct dec_data {
short int d2[NTMAX*RX_SAMPLE_RATE]; // sample frame buffer for sample collection
struct
{
int nutc; //UTC as integer, HHMM
bool ndiskdat; //true ==> data read from *.wav file
int ntrperiod; //TR period (seconds)
int nQSOProgress; /* QSO state machine state */
int nfqso; //User-selected QSO freq (kHz)
int nftx; /* Transmit audio offset where
replies might be expected */
bool newdat; //true ==> new data, must do long FFT
int npts8; //npts for c0() array
int nfa; //Low decode limit (Hz)
int nfSplit; //JT65 | JT9 split frequency
int nfb; //High decode limit (Hz)
int ntol; //+/- decoding range around fQSO (Hz)
int nutc; // UTC as integer, HHMM
bool ndiskdat; // true ==> data read from *.wav file
int ntrperiod; // TR period (seconds)
int nQSOProgress; // QSO state machine state
int nfqso; // User-selected QSO freq (kHz)
int nftx; // Transmit audio offset where replies might be expected
bool newdat; // true ==> new data, must do long FFT
int npts8; // npts for c0() array
int nfa; // Low decode limit (Hz) (filter min)
int nfSplit; // JT65 | JT9 split frequency
int nfb; // High decode limit (Hz) (filter max)
int ntol; // +/- decoding range around fQSO (Hz)
int kin; // number of frames written to d2
int kposA; // starting position of decode for submode A
int kposB; // starting position of decode for submode B
@ -109,8 +108,8 @@ extern struct dec_data {
int kszE; // number of frames for decode for submode E
int kszI; // number of frames for decode for submode I
int nzhsym; // half symbol stop index
int nsubmode;
int nsubmodes;
int nsubmode; // which submode to decode (-1 if using nsubmodes)
int nsubmodes; // which submodes to decode
bool nagain;
int ndepth;
bool lft8apon;

View File

@ -2534,6 +2534,18 @@ int MainWindow::computePeriodForSubmode(int submode){
return 0;
}
int MainWindow::computeBandwidthForSubmode(int submode){
switch(submode){
case Varicode::JS8CallNormal: return 8 * RX_SAMPLE_RATE / JS8A_SYMBOL_SAMPLES;
case Varicode::JS8CallFast: return 8 * RX_SAMPLE_RATE / JS8B_SYMBOL_SAMPLES;
case Varicode::JS8CallTurbo: return 8 * RX_SAMPLE_RATE / JS8C_SYMBOL_SAMPLES;
case Varicode::JS8CallSlow: return 8 * RX_SAMPLE_RATE / JS8E_SYMBOL_SAMPLES;
case Varicode::JS8CallUltra: return 8 * RX_SAMPLE_RATE / JS8I_SYMBOL_SAMPLES;
}
return 0;
}
int MainWindow::computeStop(int submode, int period){
int stop = 0;
@ -4357,9 +4369,6 @@ bool MainWindow::decodeProcessQueue(qint32 *pSubmode){
dec_data.params.nagain=0;
dec_data.params.nzhsym=m_ihsym;
dec_data.params.nfa=m_wideGraph->nStartFreq();
dec_data.params.nfb=m_wideGraph->Fmax();
if(dec_data.params.nagain==0 && dec_data.params.newdat==1 && (!m_diskData)) {
qint64 ms = DriftingDateTime::currentMSecsSinceEpoch() % 86400000;
int imin=ms/60000;
@ -4407,6 +4416,13 @@ bool MainWindow::decodeProcessQueue(qint32 *pSubmode){
dec_data.params.nfSplit=m_wideGraph->Fmin();
dec_data.params.nfb=m_wideGraph->Fmax();
int filter = max(0, m_wideGraph->filter());
if(filter){
int f = currentFreqOffset() + computeBandwidthForSubmode(submode)/2;
dec_data.params.nfa=max(0, f - filter/2);
dec_data.params.nfb=min(f + filter/2, 5000);
}
//if(m_mode=="FT8" and m_config.bHound() and !ui->cbRxAll->isChecked()) dec_data.params.nfb=1000;
//if(m_mode=="FT8" and m_config.bFox()) dec_data.params.nfqso=200;
@ -7534,6 +7550,8 @@ void MainWindow::on_actionJS8_triggered()
updateModeButtonText();
m_wideGraph->setSubMode(m_nSubMode);
m_wideGraph->setFilterMinimum(computeBandwidthForSubmode(m_nSubMode));
bool bVHF=m_config.enable_VHF_features();
enable_DXCC_entity (m_config.DXCC ());
switch_mode (Modes::JS8);

View File

@ -943,6 +943,7 @@ private:
void statusChanged();
void fixStop();
int computePeriodForSubmode(int submode);
int computeBandwidthForSubmode(int submode);
int computeStop(int submode, int period);
//int computeCurrentCycle(int period);
//int computeCycleStartForDecode(int cycle, int period);

View File

@ -28,6 +28,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
m_plot2dGain {0},
m_plot2dZero {0},
m_nSubMode {0},
m_filterWidth {0},
m_turbo {false},
m_Running {false},
m_paintEventBusy {false},
@ -86,6 +87,8 @@ void CPlotter::resizeEvent(QResizeEvent* ) //resizeEvent()
m_h1=m_h-m_h2;
// m_line=0;
m_FilterOverlayPixmap = QPixmap(m_Size.width(), m_h);
m_FilterOverlayPixmap.fill(Qt::transparent);
m_DialOverlayPixmap = QPixmap(m_Size.width(), m_h);
m_DialOverlayPixmap.fill(Qt::transparent);
m_HoverOverlayPixmap = QPixmap(m_Size.width(), m_h);
@ -120,6 +123,10 @@ void CPlotter::paintEvent(QPaintEvent *) // paint
painter.drawPixmap(m_lastMouseX, 0, m_HoverOverlayPixmap);
}
if(m_filterWidth > 0){
painter.drawPixmap(0, 0, m_FilterOverlayPixmap);
}
m_paintEventBusy=false;
}
@ -467,7 +474,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
}
// paint dials and filter overlays
if(m_mode=="FT8"){
int fwidth=XfromFreq(m_rxFreq+bw)-XfromFreq(m_rxFreq);
#if TEST_FOX_WAVE_GEN
@ -523,6 +530,28 @@ void CPlotter::DrawOverlay() //DrawOverlay()
hoverPainter.setFont(Font);
hoverPainter.drawText(fwidth + 5, m_h, QString("%1").arg(f));
#endif
if(m_filterWidth > 0){
int filterStart=XfromFreq(m_rxFreq+bw/2-m_filterWidth/2);
int filterEnd=XfromFreq(m_rxFreq+bw/2+m_filterWidth/2);
// TODO: make sure filter is visible before painting...
QPainter filterPainter(&m_FilterOverlayPixmap);
filterPainter.initFrom(this);
filterPainter.setCompositionMode(QPainter::CompositionMode_Source);
filterPainter.fillRect(0, 0, m_Size.width(), m_h, Qt::transparent);
QPen thinYellow(Qt::yellow, 1);
filterPainter.setPen(thinYellow);
filterPainter.drawLine(filterStart, 30, filterStart, m_h);
filterPainter.drawLine(filterEnd, 30, filterEnd, m_h);
QColor blackMask(0, 0, 0, 128);
filterPainter.fillRect(0, 30, filterStart, m_h, blackMask);
filterPainter.fillRect(filterEnd+1, 30, m_Size.width(), m_h, blackMask);
}
}
}
@ -786,6 +815,13 @@ void CPlotter::setTurbo(bool turbo)
update();
}
void CPlotter::setFilter(int width)
{
m_filterWidth=width;
DrawOverlay();
update();
}
void CPlotter::setFlatten(bool b1, bool b2)
{
m_Flatten=0;

View File

@ -82,6 +82,7 @@ public:
void setTol(int n);
void setRxBand(QString band);
void setTurbo(bool turbo);
void setFilter(int width);
#if JS8_USE_REFSPEC
void setReference(bool b) {m_bReference = b;}
bool Reference() const {return m_bReference;}
@ -135,6 +136,7 @@ private:
qint32 m_ia;
qint32 m_ib;
QPixmap m_FilterOverlayPixmap;
QPixmap m_DialOverlayPixmap;
QPixmap m_HoverOverlayPixmap;
QPixmap m_WaterfallPixmap;
@ -150,6 +152,7 @@ private:
QString m_rxBand;
QString m_redFile;
int m_filterWidth;
bool m_turbo;
bool m_Running;
bool m_paintEventBusy;

View File

@ -10,6 +10,7 @@
#include "SettingsGroup.hpp"
#include "DriftingDateTime.h"
#include "keyeater.h"
#include "moc_widegraph.cpp"
@ -35,6 +36,16 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
setMaximumWidth (MAX_SCREENSIZE);
setMaximumHeight (880);
auto filterEscapeEater = new KeyPressEater();
connect(filterEscapeEater, &KeyPressEater::keyPressed, this, [this](QObject */*obj*/, QKeyEvent *e, bool *pProcessed){
if(e->key() != Qt::Key_Escape){
return;
}
setFilter(0);
if(pProcessed) *pProcessed=true;
});
ui->filterSpinBox->installEventFilter(filterEscapeEater);
ui->widePlot->setCursor(Qt::CrossCursor);
ui->widePlot->setMaximumHeight(800);
ui->widePlot->setCurrent(false);
@ -99,6 +110,9 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
setRxRange ();
ui->controls_widget->setVisible(!m_settings->value("HideControls", false).toBool());
ui->cbControls->setChecked(!m_settings->value("HideControls", false).toBool());
setFilter(m_settings->value("FilterWidth", 0).toInt());
setFilterEnabled(m_settings->value("FilterEnabled", false).toBool());
}
int index=0;
@ -155,6 +169,8 @@ void WideGraph::saveSettings() //saveS
m_settings->setValue ("HideControls", ui->controls_widget->isHidden ());
m_settings->setValue ("FminPerBand", m_fMinPerBand);
m_settings->setValue ("CenterOffset", ui->centerSpinBox->value());
m_settings->setValue ("FilterWidth", m_filterWidth);
m_settings->setValue ("FilterEnabled", m_filterEnabled);
}
void WideGraph::drawRed(int ia, int ib)
@ -309,6 +325,39 @@ int WideGraph::Fmax() //Fmax
return std::min(5000,ui->widePlot->Fmax());
}
int WideGraph::filter()
{
return m_filterEnabled ? m_filterWidth : 0;
}
void WideGraph::setFilter(int width){
if(width == m_filterWidth){
return;
}
// update the filter history
m_filterWidthPrev = m_filterWidth;
m_filterWidth = width;
// update the spinner UI
ui->filterSpinBox->setValue(width);
// update the wide plot UI
ui->widePlot->setFilter(width);
}
void WideGraph::setFilterMinimum(int width){
ui->filterSpinBox->setMinimum(width);
}
void WideGraph::setFilterEnabled(bool enabled){
m_filterEnabled = enabled;
// update the wide plot with the
ui->widePlot->setFilter(enabled ? m_filterWidth : 0);
ui->filterSpinBox->setEnabled(enabled);
}
int WideGraph::fSpan()
{
return ui->widePlot->fSpan ();
@ -568,6 +617,14 @@ void WideGraph::on_sbPercent2dPlot_valueChanged(int n)
ui->widePlot->SetPercent2DScreen(n);
}
void WideGraph::on_filterSpinBox_valueChanged(int n){
setFilter(n);
}
void WideGraph::on_filterCheckBox_toggled(bool b){
setFilterEnabled(b);
}
void WideGraph::setRedFile(QString fRed)
{
ui->widePlot->setRedFile(fRed);

View File

@ -33,6 +33,10 @@ public:
int nStartFreq();
int Fmin();
int Fmax();
int filter();
void setFilter(int width);
void setFilterMinimum(int width);
void setFilterEnabled(bool enabled);
int fSpan();
void saveSettings();
void setFsample(int n);
@ -89,6 +93,8 @@ private slots:
void on_zero2dSlider_valueChanged(int value);
void on_smoSpinBox_valueChanged(int n);
void on_sbPercent2dPlot_valueChanged(int n);
void on_filterSpinBox_valueChanged(int n);
void on_filterCheckBox_toggled(bool b);
private:
void readPalette ();
@ -102,6 +108,10 @@ private:
WFPalette m_userPalette;
QHash<QString, QVariant> m_fMinPerBand;
bool m_filterEnabled;
qint32 m_filterWidth;
qint32 m_filterWidthPrev;
qint32 m_waterfallAvg;
qint32 m_TRperiod;
qint32 m_nsps;

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1083</width>
<width>1166</width>
<height>154</height>
</rect>
</property>
@ -103,7 +103,14 @@
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="12">
<item row="1" column="7">
<widget class="QComboBox" name="paletteComboBox">
<property name="toolTip">
<string>Select waterfall palette</string>
</property>
</widget>
</item>
<item row="0" column="13">
<widget class="QSlider" name="zeroSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -140,32 +147,24 @@
</property>
</widget>
</item>
<item row="0" column="13">
<widget class="QSpinBox" name="sbPercent2dPlot">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set fractional size of spectrum in this window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string> %</string>
</property>
<property name="prefix">
<string>Spec </string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>0</number>
<item row="0" column="6" rowspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="8">
<item row="0" column="1">
<widget class="QPushButton" name="qsyPushButton">
<property name="text">
<string>QSY</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="9">
<widget class="QComboBox" name="spec2dComboBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select data for spectral display&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -190,59 +189,7 @@
</item>
</widget>
</item>
<item row="0" column="8">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="cbFlatten">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Flatten spectral baseline over the full displayed interval.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Flatten</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbRef">
<property name="visible">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Compute and save a reference spectrum. (Not yet fully implemented.)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Ref Spec</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="bppSpinBox">
<property name="toolTip">
<string>Compression factor for frequency scale</string>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="1" column="12">
<item row="1" column="13">
<widget class="QSlider" name="zero2dSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -301,51 +248,60 @@
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="paletteComboBox">
<property name="toolTip">
<string>Select waterfall palette</string>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="QSlider" name="gainSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
<item row="1" column="14">
<widget class="QSpinBox" name="smoSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Waterfall gain</string>
<string>Smoothing of Linear Average spectrum</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Smooth </string>
</property>
<property name="minimum">
<number>-50</number>
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
<number>7</number>
</property>
</widget>
</item>
<item row="1" column="10">
<item row="2" column="3">
<widget class="QSpinBox" name="fSplitSpinBox">
<property name="visible">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Decode JT9 only above this frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> JT9</string>
</property>
<property name="prefix">
<string>JT65 </string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>3000</number>
</property>
</widget>
</item>
<item row="1" column="11">
<widget class="QSlider" name="gain2dSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -382,135 +338,7 @@
</property>
</widget>
</item>
<item row="0" column="14" rowspan="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="4">
<widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
</widget>
</item>
<item row="1" column="13">
<widget class="QSpinBox" name="smoSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Smoothing of Linear Average spectrum</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Smooth </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="offsetSpinBox">
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Offset </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>1500</number>
</property>
</widget>
</item>
<item row="0" column="7" rowspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="5" rowspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="fSplitSpinBox">
<property name="visible">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Decode JT9 only above this frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="suffix">
<string> JT9</string>
</property>
<property name="prefix">
<string>JT65 </string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>3000</number>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="6">
<item row="0" column="7">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labPalette">
@ -537,15 +365,45 @@
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="qsyPushButton">
<property name="text">
<string>QSY</string>
<item row="0" column="0" rowspan="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="autoDefault">
<bool>false</bool>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="0" column="9">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="cbFlatten">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Flatten spectral baseline over the full displayed interval.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Flatten</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbRef">
<property name="visible">
<bool>false</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Compute and save a reference spectrum. (Not yet fully implemented.)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Ref Spec</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="centerSpinBox">
@ -566,6 +424,180 @@
</property>
</widget>
</item>
<item row="0" column="14">
<widget class="QSpinBox" name="sbPercent2dPlot">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set fractional size of spectrum in this window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="suffix">
<string> %</string>
</property>
<property name="prefix">
<string>Spec </string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QSpinBox" name="offsetSpinBox">
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Offset </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>1500</number>
</property>
</widget>
</item>
<item row="0" column="15" rowspan="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="8" rowspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="waterfallAvgSpinBox">
<property name="toolTip">
<string>Number of FFTs averaged (controls waterfall scrolling rate)</string>
</property>
<property name="prefix">
<string>N Avg </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>50</number>
</property>
</widget>
</item>
<item row="0" column="11">
<widget class="QSlider" name="gainSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Waterfall gain</string>
</property>
<property name="minimum">
<number>-50</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QSpinBox" name="bppSpinBox">
<property name="toolTip">
<string>Compression factor for frequency scale</string>
</property>
<property name="suffix">
<string/>
</property>
<property name="prefix">
<string>Bins/Pixel </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QCheckBox" name="filterCheckBox">
<property name="text">
<string>Enable Filter</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QSpinBox" name="filterSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="specialValueText">
<string/>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="prefix">
<string>Filter </string>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -579,9 +611,6 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>offsetSpinBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>