From 949a103b2511e369543244e71831095cdbdbd47b Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 3 Oct 2022 00:23:47 +0200 Subject: [PATCH] Spectrum markers peaks option --- doc/img/Spectrum_Markers_dialog.png | Bin 18603 -> 20679 bytes doc/img/Spectrum_Markers_dialog.xcf | Bin 58310 -> 65789 bytes doc/img/Spectrum_Markers_dialog_hist.png | Bin 15257 -> 17042 bytes doc/img/Spectrum_Markers_dialog_hist.xcf | Bin 72050 -> 82672 bytes sdrbase/CMakeLists.txt | 2 + sdrbase/dsp/spectrumsettings.cpp | 3 + sdrbase/dsp/spectrumsettings.h | 2 + sdrbase/util/peakfinder.cpp | 55 ++++++++++++++++ sdrbase/util/peakfinder.h | 48 ++++++++++++++ sdrgui/gui/glspectrum.h | 2 + sdrgui/gui/glspectrumgui.cpp | 1 + sdrgui/gui/glspectrumview.cpp | 79 +++++++++++++++++++++-- sdrgui/gui/glspectrumview.h | 8 ++- sdrgui/gui/spectrummarkers.md | 5 ++ sdrgui/gui/spectrummarkersdialog.cpp | 15 ++++- sdrgui/gui/spectrummarkersdialog.h | 3 + sdrgui/gui/spectrummarkersdialog.ui | 25 +++++++ 17 files changed, 241 insertions(+), 7 deletions(-) create mode 100644 sdrbase/util/peakfinder.cpp create mode 100644 sdrbase/util/peakfinder.h diff --git a/doc/img/Spectrum_Markers_dialog.png b/doc/img/Spectrum_Markers_dialog.png index 8206bf399d1781b1f6de480a98065decaecbdd2a..219b61962de03225615a045a6734bdd8cee6a155 100644 GIT binary patch literal 20679 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 F)ZcmWVE6z4 literal 18603 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 AI{*Lx diff --git a/doc/img/Spectrum_Markers_dialog.xcf b/doc/img/Spectrum_Markers_dialog.xcf index bbd39f3edf3a744fd89d15cdd3004742009f2043..877a8dfc615b0fcc6bc377dfd63755a36ba06197 100644 GIT binary patch delta 8803 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 L9eMu!o6P?Uhf$pQ delta 1460 zcmY+^L1+^}7>40&y0ln9N(lvf2u4E>6+M(7Qm9HARC*AVC{j>Ff?&lSBuep+MF|QD zQr*Qvjv53#h>}31pi+qy1r=to}Z|is_;!XI?#z4aeJo$g0cGKh0T2C7rfaDwAi+wZV=C9(`F)=(X4vu<^=4i(y2@b3gkI#yU3*wcC zXsr@ctHm4b;_Wx$-Roj@NSt^i-k%pIE8-L{`fUAS30}OyclZ$(#F?Gq>R0 zw6H?zLLjqy+r9~Jam-xV)@>BC5?AtA#n1RdbbGJ*Hf==eQXG?LVH%mYl%r<;QjNOa z)bPyd63qE9h#`z%6k{02BwCopEaoteHLSa;#V+d-lzkY)5JoVHF^pppElgt;bC|~( z)|KvNtLPF`d>F(KMlgyojAIflOk);vqIz1#vTM=k$UJED>qhnQlEu~J?&@#RxrS_H z=MMFx==MuDhW$`-Tg~YMnN?RCBt~k8809dvPQ7;U?_IEf~h_IE1@!FBFPwLi<|_?iF! diff --git a/doc/img/Spectrum_Markers_dialog_hist.png b/doc/img/Spectrum_Markers_dialog_hist.png index bfc2ef8fa09a3de2ee9bc22c4cd71346b65cf179..f38bfa1a7226580f38c13b03c6f43b81b3574199 100644 GIT binary patch literal 17042 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 C$E6DZ literal 15257 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 PVkyb1zAS!W^6CEp6js#= diff --git a/doc/img/Spectrum_Markers_dialog_hist.xcf b/doc/img/Spectrum_Markers_dialog_hist.xcf index 6794faf3df4d07ab2aac220cb8e71e729acc95c0..4f0878175ccb712dd7aa8cc4b1164c34d38b09e3 100644 GIT binary patch delta 15053 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 delta 5389 zcmb{0e{dA#8Nl(~y@Z6H`E@z&0tuuv;Xp%!5MT(wg9IfadK5!IAQKxRlxUkY17wO} z&&CKMf#8-Q)=FiN0v0;r$`Dh+lYd&N<@c;6H;f2s21;WX?0`sUcjoQ2n|^45HNOTsMOh$(lrOEY4gaW{{3*2VnN&Pv)6o8)tryS@4p zTEAJImeyy5i;|KT`{3rfL>=%avaX6002eA|v;|isz z^;=D1Gw#6s_<@+f=a;ZR;v_zoq+P`C;GgiX_yv9~CiljGt93H8%PQ~vu+`o>Z0aL4 zUpV-k<_YI(J>9-Lh8fqcsgc`EXXv*7H&2^0bPu=g`}ehV4V~?bnjJLVH`P4Z&d@#F zqWc!3LwAN!BSEb*lG+*61_*Z|ot^E;k)U8oJ?2CH+y^r zc)E5T9mtFho$X}0noIz*XJ*2&_g4gp>%C%XJ;h(o*uc=?u6FcYpjfPjVQX3 z4V_NT4y@xN58Hb(?&^lO(i&ZxW_X`J%hq+%XWtq+$7A^8)ZNgZFIWGN6dZ#0 zsJmfchJ=CnScNO`MSKN+hkw8i@$YyU|0|~T#X)!v<||DtZ3cFBePc3G;>3=rkOkJt2xid7}-Bi^~|o2{yArn zyKT-*RnOtIk{;fG7H&fu58_F@fH%aT2UBnuj=@5ljTK5$3)YfoKnu5tIq8^#1;|rF z&O+j+u^yZ7RosK`;W5{4^$giJ##Y4{xdBzr+`MQ#b7wkp)Nk*ebk;D&6sekysgr%= zC*oiXs+x{nBjMN<+=;Dt1kd0_ye;O%qaTAf7nfiiuE7?ispah?(TYdJi6IPQIaXr? zoAEV#6Wj3E`Bh^m~utcaB8OXDPD%pVw0+2 zp*(|Wg;OM5I18V^8l+p{M&hlw7ypRI@gI0yEYdLvGnJ-RG@8T|oFz`*j{EQsp27~i zDHgjAfX=Hp6|*o8r(p?Jx^|nFx%Sp@Nt`ibud3&aW6^rf=uq>rXl}B{cr;1X^ilRz zI#l*m$`f?y1Xa^8Lxj~3nigIrn}r*36K=RIaXr?oAEV#6Wj3i;q5qM-U3zAd3Dj6&TCfR zM^`FGc#H+dRZSOia*KX1`&`t9hgD6>IOj6Xxr}ozlXKR}IOVcR=~lK38*vkE$9;GR zPhkh%6o2%6rKweLTongoMFqclD$WsK#c#z$126+e;beRS%kU?-3fJQnS85uvi>p45 zGoHMp>bbaAw4RGI?8@2+9%JcTRm-L8q;CzMf6W8LKUB4>`n7~ryYXG*cUsk_#9!ha z@u_||81KbN_%JTOr|=oEdZg0SsyVLehgk7AF2$eYTKpBhfo=F_{2N}vZ^W8Dn1&-= zspTa5Xx+bh8MVuuA`a4Da!YBI*T(2?*w@Wr9%K2(s+21{(sflHa+_K;Q|dUdYe-#%$to_yEokS2NvScw6EZxJ#{Nx~@Ab`E^(DuF}++IIgC2S<#e( z1vnEI;?r1 m_histogramMarkers; QList m_waterfallMarkers; QList m_annoationMarkers; + bool m_findHistogramPeaks; MarkersDisplay m_markersDisplay; QList m_calibrationPoints; bool m_useCalibration; @@ -149,6 +150,7 @@ public: QList& getHistogramMarkers() { return m_histogramMarkers; } QList& getWaterfallMarkers() { return m_waterfallMarkers; } + bool getHistogramFindPeaks() { return m_findHistogramPeaks; } static int getAveragingMaxScale(AveragingMode averagingMode); //!< Max power of 10 multiplier to 2,5,10 base ex: 2 -> 2,5,10,20,50,100,200,500,1000 static int getAveragingValue(int averagingIndex, AveragingMode averagingMode); diff --git a/sdrbase/util/peakfinder.cpp b/sdrbase/util/peakfinder.cpp new file mode 100644 index 000000000..a2c0f8a56 --- /dev/null +++ b/sdrbase/util/peakfinder.cpp @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 F4EXB // +// written by Edouard Griffiths // +// // +// Find peaks in a series of real values // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "peakfinder.h" + +PeakFinder::PeakFinder() : + m_prevValue(0.0), + m_index(0) +{} + +PeakFinder::~PeakFinder() +{} + +void PeakFinder::init(Real value) +{ + m_prevValue = value; + m_peaks.clear(); + m_index = 0; +} + +void PeakFinder::push(Real value, bool last) +{ + Real diff = value - m_prevValue; + + if (diff < 0) { + m_peaks.push_back({m_prevValue, m_index}); + } else if (last) { + m_peaks.push_back({value, m_index}); + } + + m_prevValue = value; + m_index++; +} + +void PeakFinder::sortPeaks() +{ + std::sort(m_peaks.rbegin(), m_peaks.rend()); // descending order of values +} diff --git a/sdrbase/util/peakfinder.h b/sdrbase/util/peakfinder.h new file mode 100644 index 000000000..64feeef40 --- /dev/null +++ b/sdrbase/util/peakfinder.h @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 F4EXB // +// written by Edouard Griffiths // +// // +// Find peaks in a series of real values // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBASE_UTIL_PEAKFINDER_H_ +#define SDRBASE_UTIL_PEAKFINDER_H_ + +#include +#include + +#include "dsp/dsptypes.h" +#include "export.h" + +class SDRBASE_API PeakFinder { +public: + PeakFinder(); + ~PeakFinder(); + + void init(Real value); + void push(Real value, bool last=false); + void sortPeaks(); + const std::vector>& getPeaks() { return m_peaks; } + +private: + Real m_prevValue; + int m_index; + std::vector> m_peaks; //!< index, value + +}; + + +#endif // SDRBASE_UTIL_PEAKFINDER_H_ diff --git a/sdrgui/gui/glspectrum.h b/sdrgui/gui/glspectrum.h index 2e784e5fe..9b50b5102 100644 --- a/sdrgui/gui/glspectrum.h +++ b/sdrgui/gui/glspectrum.h @@ -95,6 +95,8 @@ public: void updateMarkersDisplay() { m_spectrum->updateMarkersDisplay(); } void updateCalibrationPoints() { m_spectrum->updateCalibrationPoints(); } SpectrumSettings::MarkersDisplay& getMarkersDisplay() { return m_spectrum->getMarkersDisplay(); } + bool& getHistogramFindPeaks() { return m_spectrum->getHistogramFindPeaks(); } + void setHistogramFindPeaks(bool value) { m_spectrum->setHistogramFindPeaks(value); } void setMarkersDisplay(SpectrumSettings::MarkersDisplay markersDisplay) { m_spectrum->setMarkersDisplay(markersDisplay); } QList& getCalibrationPoints() { return m_spectrum->getCalibrationPoints(); } void setCalibrationPoints(const QList& calibrationPoints) { m_spectrum->setCalibrationPoints(calibrationPoints); } diff --git a/sdrgui/gui/glspectrumgui.cpp b/sdrgui/gui/glspectrumgui.cpp index 53fbae5df..2ea4ba314 100644 --- a/sdrgui/gui/glspectrumgui.cpp +++ b/sdrgui/gui/glspectrumgui.cpp @@ -463,6 +463,7 @@ void GLSpectrumGUI::on_markers_clicked(bool checked) m_glSpectrum->getWaterfallMarkers(), m_glSpectrum->getAnnotationMarkers(), m_glSpectrum->getMarkersDisplay(), + m_glSpectrum->getHistogramFindPeaks(), m_calibrationShiftdB, this ); diff --git a/sdrgui/gui/glspectrumview.cpp b/sdrgui/gui/glspectrumview.cpp index ea37d0a9e..fd00b0a58 100644 --- a/sdrgui/gui/glspectrumview.cpp +++ b/sdrgui/gui/glspectrumview.cpp @@ -48,6 +48,7 @@ const float GLSpectrumView::m_annotationMarkerHeight = 20.0f; GLSpectrumView::GLSpectrumView(QWidget* parent) : QOpenGLWidget(parent), m_markersDisplay(SpectrumSettings::MarkersDisplaySpectrum), + m_histogramFindPeaks(false), m_cursorState(CSNormal), m_cursorChannel(0), m_spectrumVis(nullptr), @@ -1369,7 +1370,7 @@ void GLSpectrumView::paintGL() } // paint current spectrum line on top of histogram - if ((m_displayCurrent) && m_currentSpectrum) + if (m_displayCurrent && m_currentSpectrum) { Real bottom = -m_powerRange; GLfloat *q3; @@ -1403,6 +1404,10 @@ void GLSpectrumView::paintGL() } { + if (m_histogramFindPeaks) { + m_peakFinder.init(m_currentSpectrum[0]); + } + // Draw line q3 = m_q3FFT.m_array; for (int i = 0; i < m_nbBins; i++) @@ -1418,6 +1423,9 @@ void GLSpectrumView::paintGL() q3[2*i] = (Real) i; q3[2*i+1] = v; + if (m_histogramFindPeaks && (i > 0)) { + m_peakFinder.push(m_currentSpectrum[i], i == m_nbBins - 1); + } } QVector4D color; @@ -1427,12 +1435,22 @@ void GLSpectrumView::paintGL() color = QVector4D(1.0f, 1.0f, 0.25f, (float) m_displayTraceIntensity / 100.0f); } m_glShaderSimple.drawPolyline(m_glHistogramSpectrumMatrix, color, q3, m_nbBins); + + if (m_histogramFindPeaks) { + m_peakFinder.sortPeaks(); + } } } - if (m_markersDisplay & SpectrumSettings::MarkersDisplaySpectrum) { + if (m_displayCurrent && m_currentSpectrum && (m_markersDisplay & SpectrumSettings::MarkersDisplaySpectrum)) + { + if (m_histogramFindPeaks) { + updateHistogramPeaks(); + } + drawSpectrumMarkers(); } + if (m_markersDisplay & SpectrumSettings::MarkersDisplayAnnotations) { drawAnnotationMarkers(); } @@ -1724,7 +1742,7 @@ void GLSpectrumView::paintGL() } m_mutex.unlock(); -} +} // paintGL // Hightlight power band for SFDR void GLSpectrumView::drawPowerBandMarkers(float max, float min, const QVector4D &color) @@ -3289,7 +3307,7 @@ void GLSpectrumView::updateHistogramMarkers() if (i > 0) { int64_t deltaFrequency = m_histogramMarkers.at(i).m_frequency - m_histogramMarkers.at(0).m_frequency; - m_histogramMarkers.back().m_deltaFrequencyStr = displayScaled( + m_histogramMarkers[i].m_deltaFrequencyStr = displayScaled( deltaFrequency, 'f', getPrecision(deltaFrequency/m_sampleRate), @@ -3297,7 +3315,7 @@ void GLSpectrumView::updateHistogramMarkers() float power0 = m_linear ? m_histogramMarkers.at(0).m_power * (m_useCalibration ? m_calibrationGain : 1.0f) : CalcDb::dbPower(m_histogramMarkers.at(0).m_power) + (m_useCalibration ? m_calibrationShiftdB : 0.0f); - m_histogramMarkers.back().m_deltaPowerStr = displayPower( + m_histogramMarkers[i].m_deltaPowerStr = displayPower( powerI - power0, m_linear ? 'e' : 'f', m_linear ? 3 : 1); @@ -3305,6 +3323,57 @@ void GLSpectrumView::updateHistogramMarkers() } } +void GLSpectrumView::updateHistogramPeaks() +{ + int j = 0; + for (int i = 0; i < m_histogramMarkers.size(); i++) + { + if (j >= (int) m_peakFinder.getPeaks().size()) { + break; + } + + int fftBin = m_peakFinder.getPeaks()[j].second; + Real power = m_peakFinder.getPeaks()[j].first; + // qDebug("GLSpectrumView::updateHistogramPeaks: %d %d %f", j, fftBin, power); + + if ((m_histogramMarkers.at(i).m_markerType == SpectrumHistogramMarker::SpectrumMarkerTypePower) || + ((m_histogramMarkers.at(i).m_markerType == SpectrumHistogramMarker::SpectrumMarkerTypePowerMax) && + (m_histogramMarkers.at(i).m_holdReset || (power > m_histogramMarkers.at(i).m_powerMax)))) + { + float binSize = m_frequencyScale.getRange() / m_nbBins; + m_histogramMarkers[i].m_fftBin = fftBin; + m_histogramMarkers[i].m_frequency = m_frequencyScale.getRangeMin() + binSize*fftBin; + m_histogramMarkers[i].m_point.rx() = binSize*fftBin / m_frequencyScale.getRange(); + + if (i == 0) + { + m_histogramMarkers[i].m_frequencyStr = displayScaled( + m_histogramMarkers[i].m_frequency, + 'f', + getPrecision((m_centerFrequency*1000)/m_sampleRate), + false + ); + } + else + { + int64_t deltaFrequency = m_histogramMarkers.at(i).m_frequency - m_histogramMarkers.at(0).m_frequency; + m_histogramMarkers[i].m_deltaFrequencyStr = displayScaled( + deltaFrequency, + 'f', + getPrecision(deltaFrequency/m_sampleRate), + true + ); + } + } + else + { + continue; + } + + j++; + } +} + void GLSpectrumView::updateWaterfallMarkers() { for (int i = 0; i < m_waterfallMarkers.size(); i++) diff --git a/sdrgui/gui/glspectrumview.h b/sdrgui/gui/glspectrumview.h index ddc7180e7..e5dcd64b5 100644 --- a/sdrgui/gui/glspectrumview.h +++ b/sdrgui/gui/glspectrumview.h @@ -43,6 +43,7 @@ #include "util/incrementalarray.h" #include "util/message.h" #include "util/colormap.h" +#include "util/peakfinder.h" class QOpenGLShaderProgram; class MessageQueue; @@ -214,11 +215,14 @@ public: QList& getAnnotationMarkers() { return m_annotationMarkers; } void setAnnotationMarkers(const QList& annotationMarkers); void updateHistogramMarkers(); + void updateHistogramPeaks(); void updateWaterfallMarkers(); void updateAnnotationMarkers(); void updateMarkersDisplay(); void updateCalibrationPoints(); - SpectrumSettings::MarkersDisplay& getMarkersDisplay() { return m_markersDisplay; } + SpectrumSettings::MarkersDisplay& getMarkersDisplay() { return m_markersDisplay; } + bool& getHistogramFindPeaks() { return m_histogramFindPeaks; } + void setHistogramFindPeaks(bool value) { m_histogramFindPeaks = value; } void setMarkersDisplay(SpectrumSettings::MarkersDisplay markersDisplay); QList& getCalibrationPoints() { return m_calibrationPoints; } void setCalibrationPoints(const QList& calibrationPoints); @@ -258,6 +262,8 @@ private: QList m_sortedAnnotationMarkers; QList m_visibleAnnotationMarkers; SpectrumSettings::MarkersDisplay m_markersDisplay; + bool m_histogramFindPeaks; + PeakFinder m_peakFinder; QList m_calibrationPoints; CursorState m_cursorState; diff --git a/sdrgui/gui/spectrummarkers.md b/sdrgui/gui/spectrummarkers.md index d845a2eb6..9f10c866b 100644 --- a/sdrgui/gui/spectrummarkers.md +++ b/sdrgui/gui/spectrummarkers.md @@ -72,6 +72,11 @@ This combo lets you select the type of marker: Use this slider to adjust the power position of the marker. The units are in dB irrespective of the linear or log set of the spectrum display. + +

11. Peak detection

+ +Activates or de-activates peak detection. With peak detection engaged markers with type "Cur" or "Max" will be automatically set to frequency (bin) of maximum power. The first marker in index order with "Cur" or "Max" will be set to the highest peak in magnitude then next marker to next peak in magnitude order etc,,, Markers of type "Cur" will track current peaks and markers of type "Max" will track peak maxima making it more suitable for transient signals. +

Waterfall markers tab

![Spectrum Markers waterfall dialog](../../doc/img/Spectrum_Markers_dialog_wat.png) diff --git a/sdrgui/gui/spectrummarkersdialog.cpp b/sdrgui/gui/spectrummarkersdialog.cpp index 28f6b9e7e..de1b54933 100644 --- a/sdrgui/gui/spectrummarkersdialog.cpp +++ b/sdrgui/gui/spectrummarkersdialog.cpp @@ -32,6 +32,7 @@ SpectrumMarkersDialog::SpectrumMarkersDialog( QList& waterfallMarkers, QList& annotationMarkers, SpectrumSettings::MarkersDisplay& markersDisplay, + bool& findPeaks, float calibrationShiftdB, QWidget* parent) : QDialog(parent), @@ -40,6 +41,7 @@ SpectrumMarkersDialog::SpectrumMarkersDialog( m_waterfallMarkers(waterfallMarkers), m_annotationMarkers(annotationMarkers), m_markersDisplay(markersDisplay), + m_findPeaks(findPeaks), m_calibrationShiftdB(calibrationShiftdB), m_histogramMarkerIndex(0), m_waterfallMarkerIndex(0), @@ -63,6 +65,7 @@ SpectrumMarkersDialog::SpectrumMarkersDialog( ui->fixedPower->setColorMapper(ColorMapper::GrayYellow); ui->fixedPower->setValueRange(false, 4, -2000, 400, 1); ui->showSelect->setCurrentIndex((int) m_markersDisplay); + ui->findPeaks->setChecked(m_findPeaks); displayHistogramMarker(); displayWaterfallMarker(); displayAnnotationMarker(); @@ -94,8 +97,12 @@ void SpectrumMarkersDialog::displayHistogramMarker() } else { + bool disableFreq = m_findPeaks && ( + (m_histogramMarkers[m_histogramMarkerIndex].m_markerType == SpectrumHistogramMarker::SpectrumMarkerTypePower) || + (m_histogramMarkers[m_histogramMarkerIndex].m_markerType == SpectrumHistogramMarker::SpectrumMarkerTypePowerMax) + ); ui->marker->setEnabled(true); - ui->markerFrequency->setEnabled(true); + ui->markerFrequency->setEnabled(!disableFreq); ui->powerMode->setEnabled(true); ui->fixedPower->setEnabled(true); ui->showMarker->setEnabled(true); @@ -403,6 +410,12 @@ void SpectrumMarkersDialog::on_powerHoldReset_clicked() m_histogramMarkers[m_histogramMarkerIndex].m_holdReset = true; } +void SpectrumMarkersDialog::on_findPeaks_toggled(bool checked) +{ + m_findPeaks = checked; + displayHistogramMarker(); +} + void SpectrumMarkersDialog::on_wMarkerFrequency_changed(qint64 value) { if (m_waterfallMarkers.size() == 0) { diff --git a/sdrgui/gui/spectrummarkersdialog.h b/sdrgui/gui/spectrummarkersdialog.h index 95e5d11ee..a732bb85d 100644 --- a/sdrgui/gui/spectrummarkersdialog.h +++ b/sdrgui/gui/spectrummarkersdialog.h @@ -39,6 +39,7 @@ public: QList& waterfallMarkers, QList& annotationMarkers, SpectrumSettings::MarkersDisplay& markersDisplay, + bool& findPeaks, float calibrationShiftdB, QWidget* parent = nullptr ); @@ -55,6 +56,7 @@ private: QList& m_waterfallMarkers; QList& m_annotationMarkers; SpectrumSettings::MarkersDisplay& m_markersDisplay; + bool &m_findPeaks; float m_calibrationShiftdB; int m_histogramMarkerIndex; int m_waterfallMarkerIndex; @@ -82,6 +84,7 @@ private slots: void on_markerDel_clicked(); void on_powerMode_currentIndexChanged(int index); void on_powerHoldReset_clicked(); + void on_findPeaks_toggled(bool checked); void on_wMarkerFrequency_changed(qint64 value); void on_timeCoarse_valueChanged(int value); diff --git a/sdrgui/gui/spectrummarkersdialog.ui b/sdrgui/gui/spectrummarkersdialog.ui index 33555e27b..f8b2cd874 100644 --- a/sdrgui/gui/spectrummarkersdialog.ui +++ b/sdrgui/gui/spectrummarkersdialog.ui @@ -498,6 +498,26 @@ Max - Marker will move according to the maximum power at the marker frequency
+ + + + + 24 + 24 + + + + Put markers in find peaks mode + + + + + + + :/dsb.png:/dsb.png + + + @@ -1799,6 +1819,11 @@ All - Show all markers QLabel
gui/clickablelabel.h
+ + ButtonSwitch + QToolButton +
gui/buttonswitch.h
+
buttonBox