Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nicer panoramic spectrum zoom #245

Merged
merged 30 commits into from
Jun 25, 2024
Merged

Conversation

sultanqasim
Copy link

Needs to be paired with changes to SuWidgets, and some changes I made to suscan also help

Also switch to fast RTT thanks to my driver changes, short buffer size,
and new RTT meaning in suscan that excludes actual retune time. Now, the
RTT is just to account for latency from buffering and transfers.
Based on new suscan logic where the discarded duration is the measured retune
time plus the user specified latency.
Forcing the two to be equal didn't really make sense. With this
independence, we can have a bunch of small FFTs of at low sample rates
combined into a bigger spectrum. Alternatively, we might want an FFT
size bigger than the spectrum size when the sample rate is high, just
so the capture duration at each frequency is reasonably long.
Capture at least one ms of data at each frequency.
The old logic didn't handle zoom nicely because scaledPsdAccum was
supposed to represent the full frequency range of the source information
while being at the target bin width. In case of zoom, the source
frequency span is bigger than the target frequency span, so it would cut
off data at its end. This cutting off of data at the end caused the end
of the resulting PSD to always have no data even though the source
contained it.

This new scaling logic is simpler, performs calculations in place
(avoiding the need for the scaled accumulator buffer), and only performs
calculations on the portion of the source frequency range that is within
the target frequency range.

Note that this new implementation no longer interpolates between
frequency bins, for simplicity and performance's sake. Instead, it just
takes the nearest bin. However, I may add back such interpolation if we
later decide it's important enough to justify the performance penalty.
Helps preserve more frequency resolution for zoom
For nice frequency zoom. TODO: make it optional
Shouldn't normally be needed unless something went wrong, though I
encountered a segfault here when I introduced a bug elsewhere. Minimal
overhead to add safety, so I'll just add a check.
Avoid using overly large spectrum sizes with redundant bins when zooming
in, since it's just wasted computation.

Also make the spectrum size a power of 2 to keep GLWaterfall's
downsampling logic happy.

Scanner: make frequency resolution a constant
Allow the waterfall's internal representation of the full range to
change size when the waterfall is restarted with a different range.
With the new partial update waterfall design, the waterfall center
frequency remains constant and accurate.
@sultanqasim
Copy link
Author

One known issue at this moment: when you stop the scanner and then zoom into the last frequency range fed into the waterfall by the scanner (pointed to by m_partialFftData in the waterfall), the data seen may be corrupted. I think this is a use-after-free due to the lifecycle of PSD data from the scanner class; need to confirm.

@BatchDrake
Copy link
Owner

I am afraid this is crashing SigDigger in my machine during startup:

Thread 1 "SigDigger" received signal SIGSEGV, Segmentation fault.
0x00007ffff7f44a12 in AbstractWaterfall::setFftPlotColor (this=0x6900630069006c, color=...) at AbstractWaterfall.cpp:1674
1674      m_FftColor = color;
(gdb) bt
#0  0x00007ffff7f44a12 in AbstractWaterfall::setFftPlotColor(QColor) (this=0x6900630069006c, color=...) at AbstractWaterfall.cpp:1674
#1  0x000055555579cbb5 in SigDigger::PanoramicDialog::setColors(SigDigger::ColorConfig const&) ()
#2  0x00005555557907db in SigDigger::UIMediator::applyConfig() ()
#3  0x000055555564a638 in SigDigger::Application::run(Suscan::Object const&) ()
#4  0x0000555555657aae in SigDigger::Loader::handleDone() ()
#5  0x00007ffff6130a7c in QObject::event(QEvent*) (this=0x7fffffffdb80, e=0x7fff94bfc3f0) at /home/qt/work/qt/qtbase/src/corelib/kernel/qobject.cpp:1365
#6  0x00007ffff7254a62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x7fffffffdb80, e=0x7fff94bfc3f0) at /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3409
#7  0x00007ffff60e301a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7fffffffdb80, event=0x7fff94bfc3f0) at /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1067
#8  0x00007ffff60e5f7c in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555556010270) at /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1834
#9  0x00007ffff634a5d3 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x555556011540) at /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279
#10 0x00007ffff47dc7a9 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#11 0x00007ffff47dca38 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#12 0x00007ffff47dcacc in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#13 0x00007ffff6349fdf in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555560afe40, flags=...) at /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:429
#14 0x0000555555657b41 in SigDigger::Loader::showMessage(QString const&) ()
#15 0x0000555555657e9a in SigDigger::Loader::handleChange(QString const&) ()
#16 0x00007ffff6130a7c in QObject::event(QEvent*) (this=0x7fffffffdb80, e=0x7fff9490bdb0) at /home/qt/work/qt/qtbase/src/corelib/kernel/qobject.cpp:1365
#17 0x00007ffff7254a62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x7fffffffdb80, e=0x7fff9490bdb0) at /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3409
#18 0x00007ffff60e301a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7fffffffdb80, event=0x7fff9490bdb0) at /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1067
#19 0x00007ffff60e5f7c in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555556010270) at /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1834
#20 0x00007ffff634a5d3 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x555556011540) at /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279
#21 0x00007ffff47dc7a9 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#22 0x00007ffff47dca38 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#23 0x00007ffff47dcacc in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#24 0x00007ffff6349fdf in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555560afe40, flags=...) at /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:429
#25 0x0000555555657b41 in SigDigger::Loader::showMessage(QString const&) ()
#26 0x0000555555657e9a in SigDigger::Loader::handleChange(QString const&) ()
#27 0x00007ffff6130a7c in QObject::event(QEvent*) (this=0x7fffffffdb80, e=0x7fff948e3350) at /home/qt/work/qt/qtbase/src/corelib/kernel/qobject.cpp:1365
#28 0x00007ffff7254a62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x7fffffffdb80, e=0x7fff948e3350) at /home/qt/work/qt/qtbase/src/widgets/kernel/qapplication.cpp:3409
#29 0x00007ffff60e301a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7fffffffdb80, event=0x7fff948e3350) at /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1067
#30 0x00007ffff60e5f7c in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555556010270) at /home/qt/work/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1834
#31 0x00007ffff634a5d3 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x555556011540) at /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279
#32 0x00007ffff47dc7a9 in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#33 0x00007ffff47dca38 in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#34 0x00007ffff47dcacc in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007ffff6349f5a in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555560afe40, flags=...) at /home/qt/work/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:429
#36 0x00007ffff60ef0bb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fffffffda50, flags=..., flags@entry=...) at /home/qt/work/qt/qtbase/src/corelib/global/qflags.h:69
#37 0x00007ffff60eb00b in QCoreApplication::exec() () at /home/qt/work/qt/qtbase/src/corelib/global/qflags.h:109
#38 0x0000555555646bb5 in main ()
(gdb) 

@BatchDrake
Copy link
Owner

It seems that PanoramicDialog::waterfall was not being initialized to nullptr in construction. I am leveraging this crash to do some style cleanup in the class (prefix private members by m_, remove this-> unless it is necessary etc). I hope to fix it in no time.

@BatchDrake
Copy link
Owner

Fixed, now I am seeing the panoramic spectrum just fine. It is almost like magic, being able to zoom in and out with OpenGL enabled here and also with the peace of mind of having a dedicated API to update partial portions of the FFT. Awesome! It will take a while for me to review all these changes, but this looks good so far.

@sultanqasim
Copy link
Author

Great, glad you like it. Thanks for catching the waterfall pointer initialization issue, I’ll add a commit for that. I also started fixing that UAF I mentioned last night, I’ll upload a fix for that once ready.

@BatchDrake
Copy link
Owner

BatchDrake commented May 16, 2024 via email

@sultanqasim
Copy link
Author

sultanqasim commented May 16, 2024

Ah, I see. I'll rebase on your https://github.com/BatchDrake/SigDigger/commits/sultanqasim-develop/ branch.

Defer destruction of the Scanner class till we restart the panoramic
spectrum so that the waterfall's reference to the Scanner's spectrum
view PSD data remains valid.
@sultanqasim
Copy link
Author

Building on top of your commit, I fixed the use-after-free issue and a couple other bugs.

Requires a corresponding change in suscan to permit it
@sultanqasim
Copy link
Author

You will also need BatchDrake/suscan#87 to support the last commit about non-hopping startup

@alphafox02
Copy link

Just a note, if I zoom in with say a 90Mhz - 100Mhz range and then try to zoom out with the scroll wheel, it doesn't actually seem to scroll out to where it first started. I have to hit stop then start to get the full range back in view within the fft/waterfall window. Also selected MHz doesn't seem to match what I'm selecting. I'm probably getting ahead of things that are still being worked out and/or doing something wrong on my end.

@BatchDrake
Copy link
Owner

BatchDrake commented May 23, 2024 via email

@sultanqasim
Copy link
Author

Just a note, if I zoom in with say a 90Mhz - 100Mhz range and then try to zoom out with the scroll wheel, it doesn't actually seem to scroll out to where it first started. I have to hit stop then start to get the full range back in view within the fft/waterfall window. Also selected MHz doesn't seem to match what I'm selecting. I'm probably getting ahead of things that are still being worked out and/or doing something wrong on my end.

Seems strange; are you sure you have the right branches built? BatchDrake’s development branches of SuScan/SuWidgets/Sigutils + this branch of SigDigger should work. I’ll message you a video of how it should be behaving.

@alphafox02
Copy link

I changed the following just now and pointed the relevant section of blsd to it. It was late last night, so when I did build it successfully I had actually reverted to it building the standard version and didn't realize it.
https://raw.githubusercontent.com/alphafox02/SigDigger/sultanqasim-develop/Scripts/dist-common.sh

# The latest sigutils is now on master
        try "Cloning sigutils (${BRANCH})..."          git clone --recurse-submodules -b master https://github.com/BatchDrake/sigutils
        try "Cloning suscan (${BRANCH})..."            git clone --recurse-submodules -b "$BRANCH" https://github.com/BatchDrake/suscan
        try "Cloning SuWidgets (${BRANCH})..."         git clone --recurse-submodules -b "$BRANCH" https://github.com/BatchDrake/SuWidgets
        try "Cloning SigDigger (${BRANCH})..."         git clone --recurse-submodules -b sultanqasim-develop https://github.com/BatchDrake/SigDigger
        try "Creating builddirs..."        mkdir -p sigutils/build suscan/build

Now that I'm back to building the correct branch(s?), I get the

[ FAILED ] Building SigDigger... 

--------------8<----------------------------------------
Try: make -j 8
CWD: /usr/src/blsd-dir/build-root/SigDigger
Audio/AudioFileSaver.cpp: In member function ‘virtual bool SigDigger::AudioFileWriter::prepare()’:
Audio/AudioFileSaver.cpp:60:12: warning: enumeration value ‘RAW’ not handled in switch [-Wswitch]
   60 |     switch (this->params.modulation) {
      |            ^
Misc/SigDiggerHelpers.cpp: In static member function ‘static void SigDigger::SigDiggerHelpers::openSaveCoherentSamplesDialog(QWidget*, const std::complex<float>*, const std::complex<float>*, size_t, qreal, int, int, Suscan::MultitaskController*)’:
Misc/SigDiggerHelpers.cpp:249:11: warning: unused parameter ‘fs’ [-Wunused-parameter]
  249 |     qreal fs,
      |     ~~~~~~^~
Panoramic/Scanner.cpp: In member function ‘void SigDigger::SpectrumView::feedLinearMode(const float*, const float*, uint64_t, double, double, bool)’:
Panoramic/Scanner.cpp:170:21: error: ‘clamp’ is not a member of ‘std’
  170 |     startBin = std::clamp(startBin, 0, static_cast<int>(psdSize - 1));
      |                     ^~~~~
Panoramic/Scanner.cpp:171:19: error: ‘clamp’ is not a member of ‘std’
  171 |     endBin = std::clamp(endBin, startBin + 1, static_cast<int>(psdSize));
      |                   ^~~~~
Panoramic/Scanner.cpp: In member function ‘void SigDigger::SpectrumView::feedHistogramMode(const float*, uint64_t, double, double)’:
Panoramic/Scanner.cpp:206:12: error: ‘clamp’ is not a member of ‘std’
  206 |   j = std::clamp(
      |            ^~~~~
make: *** [Makefile:54240: Scanner.o] Error 1
make: *** Waiting for unfinished jobs....
In member function ‘void QVector<T>::append(const T&) [with T = Suscan::LoggerMessage]’:
cc1plus: warning: writing 16 bytes into a region of size 0 [-Wstringop-overflow=]
In file included from ../../../../include/x86_64-linux-gnu/qt5/QtCore/qbytearray.h:46,
                 from ../../../../include/x86_64-linux-gnu/qt5/QtCore/qstring.h:50,
                 from ../../../../include/x86_64-linux-gnu/qt5/QtCore/qobject.h:47,
                 from ../../../../include/x86_64-linux-gnu/qt5/QtWidgets/qwidget.h:45,
                 from ../../../../include/x86_64-linux-gnu/qt5/QtWidgets/qdialog.h:44,
                 from ../../../../include/x86_64-linux-gnu/qt5/QtWidgets/QDialog:1,
                 from include/LogDialog.h:22,
                 from Components/LogDialog.cpp:20:
../../../../include/x86_64-linux-gnu/qt5/QtCore/qarraydata.h:129:8: note: at offset [40, 64] into destination object ‘QTypedArrayData<Suscan::LoggerMessage>::<anonymous>’ of size 24
  129 | struct QTypedArrayData
      |        ^~~~~~~~~~~~~~~
cc1plus: warning: writing 16 bytes into a region of size 0 [-Wstringop-overflow=]
../../../../include/x86_64-linux-gnu/qt5/QtCore/qarraydata.h:129:8: note: at offset [72, 96] into destination object ‘QTypedArrayData<Suscan::LoggerMessage>::<anonymous>’ of size 24
cc1plus: warning: writing 16 bytes into a region of size 0 [-Wstringop-overflow=]
../../../../include/x86_64-linux-gnu/qt5/QtCore/qarraydata.h:129:8: note: at offset [112, 136] into destination object ‘QTypedArrayData<Suscan::LoggerMessage>::<anonymous>’ of size 24
--------------8<----------------------------------------

@alphafox02
Copy link

alphafox02 commented May 23, 2024

Searching seems to point to the
error: ‘clamp’ is not a member of ‘std’
being related to it being C++17 exclusive and to "compile in that mode".

@sultanqasim
Copy link
Author

I was able to reproduce the error stopping the scanner on Linux. I'll look into this when I have a moment.

We won't be using it again, and deleting it is necessary to properly
stop it, so just delete it. We only need to hold onto the spectrum views
used by the panoramic dialog.
@sultanqasim
Copy link
Author

Deleting the analyzer on stop should make the stopping work like before from suscan's perspective, and there was no need to keep it around anyway, since we just needed the spectrum views in the scanner. Now stopping it works properly on Linux.

@alphafox02
Copy link

Probably, since changes for this feature span SigDigger, Susan and SuWidgets. I haven't finished the review yet. El jue., 23 may. 2024 5:24, alphafox02 @.> escribió:

Just a note, if I zoom in with say a 90Mhz - 100Mhz range and then try to zoom out with the scroll wheel, it doesn't actually seem to scroll out to where it first started. I have to hit stop then start to get the full range back in view within the fft/waterfall window. Also selected MHz doesn't seem to match what I'm selecting. I'm probably getting ahead of things that are still being worked out and/or doing something wrong on my end. — Reply to this email directly, view it on GitHub <#245 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEVET6TKTYT7WC7GAICM3LZDVOOZAVCNFSM6AAAAABHY7DL6KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRWGE2TSNJUGM . You are receiving this because you commented.Message ID: @.
>

I’m going to try the change suggested here to the .pro file

https://forum.qt.io/topic/84269/can-i-use-clang-with-std-c-17-in-qmake

@alphafox02
Copy link

Modifying the SigDigger.pro to CONFIG += c++1z allows me to build this PR. May need to account for this need on 22.04 or other systems.

Scanner now uses std::clamp from C++17
@sultanqasim
Copy link
Author

Modifying the SigDigger.pro to CONFIG += c++1z allows me to build this PR. May need to account for this need on 22.04 or other systems.

Hopefully my last patch will fix build for you

Red Hat family distributions put libraries in `/usr/lib64` instead of
`/usr/lib`. This includes sigutils getting put in `$DEPLOYROOT/usr/lib64`.
@sultanqasim
Copy link
Author

I also put up an unrelated change to fix build on Fedora

In case the user changed the frequency range right before clicking start
on the panoramic spectrum, a signal to update the view range will make
its way here before the first PSD arrives.

I'm keeping the logic to set the spectrum view range based off the
sample rate in fixed frequency mode when the sample rate is known so
that we are not discarding potentially useful data about what's happening
on nearby out-of-view channels when zoomed in. It isn't necessary to do
this (in fact its more efficient to only keep the frequency range we are
currently looking at in the spectrum view), but maybe someone would like
to zoom out and see what was happening on nearby out-of-view frequencies
while they were zoomed in.
@sultanqasim
Copy link
Author

sultanqasim commented May 27, 2024

Sorry about my flip-flopping force pushes regarding the last commit around how to handle frequency range updates in non-hopping mode. After some initial thought I removed the logic to base the spectrum view range on the sample rate altogether, but later decided to bring it back because there is one situation where it could be useful: looking at what happened on channels outside the zoomed view when zooming back out or panning in the OpenGL waterfall.

Anyway, this is working well for me on Linux and Mac and should be ready to be merged. Also have a look at my latest SuWidgets pull request; I have a couple bug fixes there.

@alphafox02
Copy link

With the change to the SigDigger.pro it builds without issue on 22.04 now with stock qt5. Just built it by changing blsd to pull dist-common from my fork of your SigDigger and all lines putting to develop on your repos. Hope that makes sense.

UIMediator::getPanSpectrumZoomRange(qint64 &min, qint64 &max, bool &noHop) const
{
if (!this->m_ui->panoramicDialog->invalidRange()) {
this->m_ui->panoramicDialog->getZoomRange(min, max, noHop);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I see this, next time you see a class with private properties starting with m_, try not to use this-> unless necessary. I used to abuse this-> in the past (perhaps because too much influence from C) I eventually made the code for big classes unreadable. The solution was, since I still wanted to clearly see in a glimpse which variables were properties, which local and which global, to remove the this-> (even for methods) and prefix private members (not methods) with m_ (and globals with g_, although this is something I was already doing in C). You will see that, once in a while, when I have to work in an existing class written in old style, I leverage the changes to rewrite them in the new style.

So, no need for you to change that (I will do it at some point in the future), just wanted to let you know (and hopefully make your life easier)!

@BatchDrake
Copy link
Owner

Hi,

I have just tested the changes. Some issues (some of them may be yours, some mine):

  • Clicking and unclicking "full device range" does not seem to affect the sweep range.
  • If we select a radio for which a sane RTT does not exist, the current RTT does not change. This is an issue if we select an USRP (2 ms) and, immediately after, something else.
  • For large RTTs (e.g. 100 ms), the waterfall becomes unresponsive. This is because it does not have information on how fast the spectrum updates are expected to come, or it thinks that it is in "fast mode", i.e. FFT updates are fast enough to refresh on each mouse interaction. See slow() in AbstractWaterfall.h.
  • Opening the panoramic spectrum dialog reverts always to the first device in the list (although I believe this was an old bug)
  • At some point I got spectrum updates (i.e. I could see the curve) but no waterfall updates. I thought this had to do with the waterfall's timespan, but since it is fixed to 30 s I doubt it. I cannot replicate it any longer.
  • There are artifacts when I zoom in and out with the mouse quickly. Some gaps are not filled with previous values, but with the lowest possible value. This is not physical (see below):

Captura de pantalla de 2024-05-29 20-32-20
Captura de pantalla de 2024-05-29 20-31-30

@sultanqasim
Copy link
Author

Thanks for your testing,

  1. For the "full device range" checkbox, I don't recall seeing the issue you described, but I'll check again.
  2. For radios for which no suggested RTT is available, are you suggested I add a slow-ish default (say 20 ms?). Keep in mind with changes I made to suscan, the RTT is now about how many milliseconds worth of samples in addition to the measured retuning time should be discarded. I made that change because different frequency jumps can take different amounts of time to retune, and some driver versions tune faster than others. The "RTT" is now mainly influenced by buffer sizes and latency rather than tuning time. Thus, the RTT label is a bit of a misnomer now; maybe I should rename it but I'm not sure of an elegant name for what it actually represents now.
  3. Good point about using slow mode for slow RTTs, I can add some logic to account for that.
  4. Defaulting to the first device in the list is unchanged behaviour, though I can look into saving the device selection for that.
  5. I'm not sure what caused that bug you described. However, while experimenting with the new RFNM SDR I just got, I encountered a couple instances of the opposite (with the regular non-panoramic main spectrum) where the waterfall was updating but the line graph stayed blank. I'll look into causes of that, though it's probably a widget bug unrelated to the panoramic spectrum functionality.
  6. The artifacts of low values on fast zoom out are due to the operation of the Scanner class and associated spectrum views. Essentially, the Scanner only keeps track of the spectrum at the current (zoomed) sweep range, and only the waterfall widget knows the previous values for the frequencies outside the current sweep range. Thus, when zooming out (flipping the spectrum view and feeding the old narrower view into the new wider one), the edges of the new wider frequency range get initialized to the minimum value until replaced by new data. In other words, it's working as designed albeit not beautiful. Perhaps filling the edges with the value from the edge of the old narrow spectrum view when zooming out would be less ugly, but I'll let you suggest what approach you want to take with that.

@sultanqasim
Copy link
Author

One other thing: because I changed the meaning of "RTT", it would be good to redetermine the default/optimal "RTT" values for the various SDRs. I did this for the RTL-SDR and USRP, though the same should also be done for the other listed SDRs that I don't have personally.

So that it can use slow rate logic for long RTTs
Behaviour change at BatchDrake's request
@sultanqasim
Copy link
Author

sultanqasim commented Jun 17, 2024

I figured out the full device range issue: it was because the frequency spin box wasn't emitting valueChanged when its value was changed through a call to setValue. Fix added to my latest SuWidgets PR.

@BatchDrake
Copy link
Owner

  1. For radios for which no suggested RTT is available, are you suggested I add a slow-ish default (say 20 ms?). Keep in mind with changes I made to suscan, the RTT is now about how many milliseconds worth of samples in addition to the measured retuning time should be discarded. I made that change because different frequency jumps can take different amounts of time to retune, and some driver versions tune faster than others. The "RTT" is now mainly influenced by buffer sizes and latency rather than tuning time. Thus, the RTT label is a bit of a misnomer now; maybe I should rename it but I'm not sure of an elegant name for what it actually represents now.

Agreed, perhaps we should call it "Device settle time"?

  1. Defaulting to the first device in the list is unchanged behaviour, though I can look into saving the device selection for that.

Yeah, just verified it. I will address it myself, don't worry about it.

  1. I'm not sure what caused that bug you described. However, while experimenting with the new RFNM SDR I just got, I encountered a couple instances of the opposite (with the regular non-panoramic main spectrum) where the waterfall was updating but the line graph stayed blank. I'll look into causes of that, though it's probably a widget bug unrelated to the panoramic spectrum functionality.

I couldn't reproduce it any longer. Perhaps it was the uninitialized variable we discussed earlier.

  1. The artifacts of low values on fast zoom out are due to the operation of the Scanner class and associated spectrum views. Essentially, the Scanner only keeps track of the spectrum at the current (zoomed) sweep range, and only the waterfall widget knows the previous values for the frequencies outside the current sweep range. Thus, when zooming out (flipping the spectrum view and feeding the old narrower view into the new wider one), the edges of the new wider frequency range get initialized to the minimum value until replaced by new data. In other words, it's working as designed albeit not beautiful. Perhaps filling the edges with the value from the edge of the old narrow spectrum view when zooming out would be less ugly, but I'll let you suggest what approach you want to take with that.

Yes, I actually prefer the extension of the values on the edges. In a bayesian sense, if I had to make a bet on the power level adjacent to the spectrum edges, I'd say "something close to the value on the edge".

I cannot test the code right now (I didn't bring any SDR with me this time), but I will test it once I am back home.

Thanks a lot!

@BatchDrake
Copy link
Owner

Testing now again

@BatchDrake BatchDrake merged commit a1651e5 into BatchDrake:develop Jun 25, 2024
2 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants