Updated waterfall to make scroll speed configurable

This commit is contained in:
Jordan Sherer 2020-04-27 16:35:37 -04:00
parent 6f5f42ffbc
commit 9f23e21d43
5 changed files with 165 additions and 44 deletions

View File

@ -3280,6 +3280,10 @@ void MainWindow::on_monitorButton_clicked (bool checked)
void MainWindow::monitor (bool state) void MainWindow::monitor (bool state)
{ {
ui->monitorButton->setChecked (state); ui->monitorButton->setChecked (state);
// make sure widegraph is running if we are monitoring, otherwise pause it.
m_wideGraph->setPaused(!state);
if (state) { if (state) {
m_diskData = false; // no longer reading WAV files m_diskData = false; // no longer reading WAV files
if (!m_monitoring) Q_EMIT resumeAudioInputStream (); if (!m_monitoring) Q_EMIT resumeAudioInputStream ();

View File

@ -172,12 +172,13 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed)
if(bScroll and swide[0]<1.e29) { if(bScroll and swide[0]<1.e29) {
flat4_(swide,&iz,&m_Flatten); flat4_(swide,&iz,&m_Flatten);
if(!m_bReplot) flat4_(&dec_data.savg[j0],&jz,&m_Flatten); //if(!m_bReplot) flat4_(&dec_data.savg[j0],&jz,&m_Flatten);
} }
ymin=1.e30; ymin=1.e30;
if(swide[0]>1.e29 and swide[0]< 1.5e30) painter1.setPen(Qt::green); // horizontal line if(swide[0]>1.e29 and swide[0]< 1.5e30) painter1.setPen(Qt::green); // horizontal line
if(swide[0]>1.4e30) painter1.setPen(Qt::yellow); if(swide[0]>1.4e30) painter1.setPen(Qt::yellow);
if(!m_bReplot) { if(!m_bReplot) {
m_j=0; m_j=0;
int irow=-1; int irow=-1;

View File

@ -1,5 +1,6 @@
#include "widegraph.h" #include "widegraph.h"
#include <algorithm> #include <algorithm>
#include <QApplication> #include <QApplication>
#include <QSettings> #include <QSettings>
@ -31,7 +32,8 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
m_filterMinimum {0}, m_filterMinimum {0},
m_filterMaximum {5000}, m_filterMaximum {5000},
m_filterEnabled {false}, m_filterEnabled {false},
m_bHaveTransmitted {false} m_bHaveTransmitted {false},
m_dist { 0.0, 0.1 }
{ {
ui->setupUi(this); ui->setupUi(this);
@ -164,6 +166,7 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
setRxRange (); setRxRange ();
ui->controls_widget->setVisible(!m_settings->value("HideControls", false).toBool()); ui->controls_widget->setVisible(!m_settings->value("HideControls", false).toBool());
ui->cbControls->setChecked(!m_settings->value("HideControls", false).toBool()); ui->cbControls->setChecked(!m_settings->value("HideControls", false).toBool());
ui->fpsSpinBox->setValue(m_settings->value ("WaterfallFPS", 4).toInt());
auto splitState = m_settings->value("SplitState").toByteArray(); auto splitState = m_settings->value("SplitState").toByteArray();
if(!splitState.isEmpty()){ if(!splitState.isEmpty()){
@ -189,6 +192,10 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
ui->paletteComboBox->addItem (user_defined); ui->paletteComboBox->addItem (user_defined);
if (user_defined == m_waterfallPalette) ui->paletteComboBox->setCurrentIndex(index); if (user_defined == m_waterfallPalette) ui->paletteComboBox->setCurrentIndex(index);
readPalette (); readPalette ();
connect(&m_drawTimer, &QTimer::timeout, this, &WideGraph::draw);
m_drawTimer.setSingleShot(true);
m_drawTimer.start(100); //### Don't change the 100 ms! ###
} }
WideGraph::~WideGraph () WideGraph::~WideGraph ()
@ -234,6 +241,7 @@ void WideGraph::saveSettings() //saveS
m_settings->setValue ("FilterEnabled", m_filterEnabled); m_settings->setValue ("FilterEnabled", m_filterEnabled);
m_settings->setValue ("FilterOpacityPercent", ui->filterOpacitySpinBox->value()); m_settings->setValue ("FilterOpacityPercent", ui->filterOpacitySpinBox->value());
m_settings->setValue ("SplitState", ui->splitter->saveState()); m_settings->setValue ("SplitState", ui->splitter->saveState());
m_settings->setValue ("WaterfallFPS", ui->fpsSpinBox->value());
} }
void WideGraph::drawRed(int ia, int ib) void WideGraph::drawRed(int ia, int ib)
@ -244,9 +252,12 @@ void WideGraph::drawRed(int ia, int ib)
void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) //dataSink2 void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) //dataSink2
{ {
static float splot[NSMAX]; static float splot[NSMAX];
QMutexLocker lock(&m_drawLock);
int nbpp = ui->widePlot->binsPerPixel(); int nbpp = ui->widePlot->binsPerPixel();
//Average spectra over specified number, m_waterfallAvg //Average spectra over specified number, m_waterfallAvg
if (m_n==0) { if (m_n==0) {
for (int i=0; i<NSMAX; i++) for (int i=0; i<NSMAX; i++)
splot[i]=s[i]; splot[i]=s[i];
@ -256,43 +267,112 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) //dat
} }
m_n++; m_n++;
if (m_n>=m_waterfallAvg) { if (m_n<m_waterfallAvg) {
for (int i=0; i<NSMAX; i++) return;
splot[i] /= m_n; //Normalize the average }
m_n=0;
int i=int(ui->widePlot->startFreq()/df3 + 0.5); for (int i=0; i<NSMAX; i++){
int jz=5000.0/(nbpp*df3); splot[i] /= m_n; //Normalize the average
if(jz>MAX_SCREENSIZE) jz=MAX_SCREENSIZE; }
m_jz=jz;
for (int j=0; j<jz; j++) { m_n=0;
float ss=0.0; int i=int(ui->widePlot->startFreq()/df3 + 0.5);
float smax=0; int jz=5000.0/(nbpp*df3);
for (int k=0; k<nbpp; k++) { if(jz>MAX_SCREENSIZE) jz=MAX_SCREENSIZE;
float sp=splot[i++]; m_jz=jz;
ss += sp; for (int j=0; j<jz; j++) {
smax=qMax(smax,sp); float ss=0.0;
} float smax=0;
// swide[j]=nbpp*smax; for (int k=0; k<nbpp; k++) {
swide[j]=nbpp*ss; float sp=splot[i++];
ss += sp;
smax=qMax(smax,sp);
} }
// Time according to this computer // swide[j]=nbpp*smax;
qint64 ms = DriftingDateTime::currentMSecsSinceEpoch() % 86400000; swide[j]=nbpp*ss;
int ntr = (ms/1000) % m_TRperiod;
if((ndiskdata && ihsym <= m_waterfallAvg) || (!ndiskdata && ntr<m_ntr0)) {
float flagValue=1.0e30;
if(m_bHaveTransmitted) flagValue=2.0e30;
for(int i=0; i<MAX_SCREENSIZE; i++) {
swide[i] = flagValue;
}
for(int i=0; i<NSMAX; i++) {
splot[i] = flagValue;
}
m_bHaveTransmitted=false;
}
m_ntr0=ntr;
ui->widePlot->draw(swide,true,false);
} }
// Time according to this computer
qint64 ms = DriftingDateTime::currentMSecsSinceEpoch() % 86400000;
int ntr = (ms/1000) % m_TRperiod;
if((ndiskdata && ihsym <= m_waterfallAvg) || (!ndiskdata && ntr<m_ntr0)) {
float flagValue=1.0e30;
if(m_bHaveTransmitted) flagValue=2.0e30;
for(int i=0; i<MAX_SCREENSIZE; i++) {
swide[i] = flagValue;
}
for(int i=0; i<NSMAX; i++) {
splot[i] = flagValue;
}
m_bHaveTransmitted=false;
}
m_ntr0=ntr;
// draw this one here too...
// ui->widePlot->draw(swide,true,false);
// copy swide around
// {
// memcpy(swide2, swide, sizeof(swide[0])*MAX_SCREENSIZE);
// }
}
void WideGraph::draw(){
static const quint64 buf = 10;
static quint64 lastLoop;
quint64 fps = qMax(1, qMin(ui->fpsSpinBox->value(), 100));
quint64 loopMs = 1000/fps * m_waterfallAvg;
quint64 thisLoop = QDateTime::currentMSecsSinceEpoch();
if(lastLoop == 0){
lastLoop = thisLoop;
}
quint64 delta = thisLoop - lastLoop;
if(delta > (loopMs + buf)){
qDebug() << "widegraph overrun" << (delta-loopMs);
}
lastLoop = thisLoop;
// do the drawing
drawSwide();
// compute the processing time and adjust loop to hit the next 100ms
auto endLoop = QDateTime::currentMSecsSinceEpoch();
auto processingTime = endLoop - thisLoop;
auto nextLoopMs = 0;
if(processingTime < loopMs){
nextLoopMs = loopMs - processingTime;
}
m_drawTimer.start(nextLoopMs);
}
void WideGraph::drawSwide(){
static bool lastSwideGreen = false;
if(m_paused){
return;
}
QMutexLocker lock(&m_drawLock);
float swideLocal[MAX_SCREENSIZE];
memcpy(swideLocal, swide, sizeof(swide[0])*MAX_SCREENSIZE);
bool thisSwideGreen = swideLocal[0] >1.e29;
for(int i = 0; i < MAX_SCREENSIZE; i++){
if(swideLocal[i] == 0.0){
swideLocal[i] += m_dist(m_gen);
}
#if 0
else if (lastSwideGreen && thisSwideGreen){
swideLocal[i] = m_dist(m_gen);
}
#endif
}
ui->widePlot->draw(swideLocal,true,false);
lastSwideGreen = thisSwideGreen;
} }
void WideGraph::on_bppSpinBox_valueChanged(int n) //bpp void WideGraph::on_bppSpinBox_valueChanged(int n) //bpp
@ -695,7 +775,6 @@ void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2
ui->widePlot->setPlot2dGain(value); ui->widePlot->setPlot2dGain(value);
if(ui->widePlot->scaleOK ()) { if(ui->widePlot->scaleOK ()) {
ui->widePlot->draw(swide,false,false); ui->widePlot->draw(swide,false,false);
if(m_mode=="QRA64") ui->widePlot->draw(swide,false,true);
} }
} }
@ -704,7 +783,6 @@ void WideGraph::on_zero2dSlider_valueChanged(int value) //Zero2
ui->widePlot->setPlot2dZero(value); ui->widePlot->setPlot2dZero(value);
if(ui->widePlot->scaleOK ()) { if(ui->widePlot->scaleOK ()) {
ui->widePlot->draw(swide,false,false); ui->widePlot->draw(swide,false,false);
if(m_mode=="QRA64") ui->widePlot->draw(swide,false,true);
} }
} }

View File

@ -2,10 +2,18 @@
#ifndef WIDEGRAPH_H #ifndef WIDEGRAPH_H
#define WIDEGRAPH_H #define WIDEGRAPH_H
#include <random>
#include <iterator>
#include <iostream>
#include <QDialog> #include <QDialog>
#include <QScopedPointer> #include <QScopedPointer>
#include <QDir> #include <QDir>
#include <QHash> #include <QHash>
#include <QTimer>
#include <QMutex>
#include <QMutexLocker>
#include <QVariant> #include <QVariant>
#include "WFPalette.hpp" #include "WFPalette.hpp"
@ -75,12 +83,16 @@ public slots:
bool controlsVisible(); bool controlsVisible();
void setDrift(int n); void setDrift(int n);
void setQSYEnabled(bool enabled); void setQSYEnabled(bool enabled);
void setPaused(bool paused){ m_paused = paused; }
protected: protected:
void keyPressEvent (QKeyEvent *e) override; void keyPressEvent (QKeyEvent *e) override;
void closeEvent (QCloseEvent *) override; void closeEvent (QCloseEvent *) override;
private slots: private slots:
void draw();
void drawSwide();
void on_qsyPushButton_clicked(); void on_qsyPushButton_clicked();
void on_offsetSpinBox_valueChanged(int n); void on_offsetSpinBox_valueChanged(int n);
void on_waterfallAvgSpinBox_valueChanged(int arg1); void on_waterfallAvgSpinBox_valueChanged(int arg1);
@ -141,14 +153,21 @@ private:
qint32 m_jz=MAX_SCREENSIZE; qint32 m_jz=MAX_SCREENSIZE;
qint32 m_n; qint32 m_n;
bool m_paused;
bool m_bFlatten; bool m_bFlatten;
bool m_bRef; bool m_bRef;
bool m_bHaveTransmitted; //Set true at end of a WSPR transmission bool m_bHaveTransmitted; //Set true at end of a WSPR transmission
QTimer m_drawTimer;
QMutex m_drawLock;
QString m_rxBand; QString m_rxBand;
QString m_mode; QString m_mode;
QString m_modeTx; QString m_modeTx;
QString m_waterfallPalette; QString m_waterfallPalette;
std::default_random_engine m_gen;
std::normal_distribution<double> m_dist;
}; };
#endif // WIDEGRAPH_H #endif // WIDEGRAPH_H

View File

@ -177,8 +177,8 @@
<widget class="QWidget" name="scrollAreaWidgetContents_2"> <widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>-3</x> <x>0</x>
<y>-163</y> <y>0</y>
<width>270</width> <width>270</width>
<height>372</height> <height>372</height>
</rect> </rect>
@ -427,9 +427,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>-193</y>
<width>267</width> <width>267</width>
<height>691</height> <height>723</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
@ -527,9 +527,28 @@
<item> <item>
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="groupBox_4">
<property name="title"> <property name="title">
<string>Averaging</string> <string>Scrolling &amp;&amp; Averaging</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QSpinBox" name="fpsSpinBox">
<property name="suffix">
<string> fps</string>
</property>
<property name="prefix">
<string>Scroll Speed: </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>