drowe67 / freedv-gui

GUI Application for FreeDV – open source digital voice for HF radio
https://freedv.org/
GNU Lesser General Public License v2.1
206 stars 52 forks source link

Waterfall maintenance #79

Closed tmiw closed 1 year ago

tmiw commented 3 years ago

Requirements:

  1. Ensure bandwidth of waterfall is sufficient to visualise fading at up to 2 Hz (we can provide test signals).
drowe67 commented 3 years ago

bandwidth is also an issue, e.g. fast enough to visualise fast fading. Plus I think CPU load is dominated by the waterfall, which affects low end machines like Pis.

Probably good to filter feature requests - it's very easy for end users to ask for something that can take up a lot of (our!) development time, and may only have very limited appeal. I tend to focus on stuff that's fun for me, or where people wanting the feature actually help code it.....

DG9BFC commented 3 years ago

i could live with lower resolution but 4 or 5 times the speed in lines per seconds ... best user setable so if you have a low end cpu switch to low resolution and speed .. mid size cpu high speed and low resolution .. fast cpu ... high speed and resolution ... that should fit all users needs

drowe67 commented 3 years ago

I suspect the CPU loadcan be dramatically reduced through optimisation of the code so it works fine without adjustment. Some profiling would help locate the bottleneck.

tmiw commented 3 years ago

I looked a little bit into it and perhaps the drawing can be done directly on the waterfall's DC object? Or at the very least, moving the current display downward prior to drawing the new pixels using the current code. I'm not sure how to handle the cases where part or all of the FreeDV window is obscured, though.

Alternatively, we can add an option to hide the spectrum, waterfall, etc. tabs and have FreeDV not render those altogether?

drowe67 commented 3 years ago

Another solution to this one is just one setting that handles all scenarios. I'd prefer set and forget to more knobs and settings.

drowe67 commented 3 years ago

@DG9BFC Can you pls explain the exact problem you are trying to solve with this feature request? What is the problem with the current waterfall speed?

DG9BFC commented 3 years ago

it is not a real problem ... and in any way only used if you send waterfall text (send mode via text in waterfall) simon added that text sending in sdr console (used to send callsign or to type a short comment in the waterfall screen) with higher speed (but then a lower resolution needed!) we could read that text message also in the freedv wf ... so ... it would just be cosmetics

drowe67 commented 3 years ago

OK - so novelty/cosmetic use is not a good reason for the FreeeDV developers to put many hours of our volunteer time into building, documenting, maintaining forever, and dealing with end user support of a feature. The focus of FreeDV is digital voice. I've removed the request for adjustable waterfall parameters from the requirements above, and will change the name of this ticket to reflect the remaining waterfall issues that do need some work.

It's becoming clear to me we need to ask people "why" they want a feature before doing (or indeed considering) any work on it....

DG9BFC commented 3 years ago

no need to spend much time on it ... i can live whatever we have now ... the higher speed (and then lower resoluion to keep cpu load low) would be just a nice add on ... a cosmetic gimmic for waterfall text ... so better use your time for things like ptt INPUT ... or solving the 800xa squelch thingy ... or ... or (i do not know your priority list / todo list) greetz sigi dg9bfc

tmiw commented 3 years ago

@drowe67, FWIW, fldigi does have a fairly configurable waterfall. It may be nice to adopt some of those options for FreeDV as well.

That said, I agree that it's pretty low priority at this point and we'll need to figure out what the use cases for those additional options are before concluding whether they'd be a good idea.

tmiw commented 3 years ago

BTW, some performance improvements have been made recently for the waterfall display (on the order of 30% minimum improvement). Those should be available in future builds and very well might partially resolve this issue.

drowe67 commented 3 years ago

Thanks @tmiw - yes you've done a fine job of characterising the CPU load and optimising the waterfall. I'll modify the OP to reflect just the remaining sub-issue.

tmiw commented 1 year ago

I generated a .raw file using the following command:

src/freedv_tx 700E ../raw/ve9qrp.raw - --reliabletext AB1CDEF --txbpf 1 --clip 1 | ./src/ch - - --No -22 --mpd -f -5 --fading_dir=./unittest > reliable_fade.raw

Playing this file back in freedv-gui seems to produce the following waterfall:

Screenshot 2023-02-22 at 9 04 00 PM

Seems like we can close this, @drowe67?

drowe67 commented 1 year ago

I'm not sure if I can actually see the impact of the fading on the spectrogram, for example notches caused by fading? That was the original issue, for fast fading it doesn't seem to be able to resolve the expected effects of fading, it just looks like an unfaded signal.

Maybe try it with fast and slow fading examples.

Here is what I see with the Octave spectrogram tool:

pkg load signal
x=load_raw("../build_linux/mpd.raw");
plot_specgram(x,8000,0,3000);

The MPD model has 4ms delay between paths, so we would expect to see notches at 1/0.004=200Hz apart:

Screenshot from 2023-02-23 17-00-23

tmiw commented 1 year ago

With --mpg (0.5 Hz fading):

Screenshot 2023-02-24 at 11 01 42 PM

With --mpp (1 Hz fading):

Screenshot 2023-02-24 at 11 02 56 PM

I can definitely see differences between all three. Still, I wonder why the --mpd case looks a lot different than the Octave spectrograph.

BTW, --mpg didn't work because slow_fading_samples.float isn't generated during the build process. I'll submit a codec2 PR to fix.

drowe67 commented 1 year ago

BTW, --mpg didn't work because slow_fading_samples.float isn't generated during the build process. I'll submit a codec2 PR to fix.

This is intentional - it's slow to generate these samples and --mpg isn't needed for any ctests (or indeed much development, it's a very benign channel).

tmiw commented 1 year ago

BTW, --mpg didn't work because slow_fading_samples.float isn't generated during the build process. I'll submit a codec2 PR to fix.

This is intentional - it's slow to generate these samples and --mpg isn't needed for any ctests (or indeed much development, it's a very benign channel).

We can probably discuss more in that PR but perhaps it could still be done in a script (but maybe not one executed when UNITTEST=1).

tmiw commented 1 year ago

Back at this again. I ended up modifying Codec2 as follows:

diff --git a/src/modem_stats.h b/src/modem_stats.h
index fbc80f74..cf92cbc5 100644
--- a/src/modem_stats.h
+++ b/src/modem_stats.h
@@ -38,8 +38,8 @@
 #define MODEM_STATS_NR_MAX      320
 #define MODEM_STATS_ET_MAX      8
 #define MODEM_STATS_EYE_IND_MAX 160
-#define MODEM_STATS_NSPEC       512
-#define MODEM_STATS_MAX_F_HZ    4000
+#define MODEM_STATS_NSPEC       1024
+#define MODEM_STATS_MAX_F_HZ    3000
 #define MODEM_STATS_MAX_F_EST   4

 struct MODEM_STATS {

and freedv-gui as follows (though I don't think the below is strictly necessary):

diff --git a/src/defines.h b/src/defines.h
index 29fac71..d54c984 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -34,7 +34,7 @@
 #define MIN_F_HZ            0       // min freq on Waterfall and Spectrum
 #define MAX_F_HZ            3000    // max freq on Waterfall and Spectrum
 #define STEP_F_HZ           500     // major (e.g. text legend) freq step on Waterfall and Spectrum graticule
-#define STEP_MINOR_F_HZ     100     // minor (ticks) freq step on Waterfall and Spectrum graticule
+#define STEP_MINOR_F_HZ     250     // minor (ticks) freq step on Waterfall and Spectrum graticule
 #define WATERFALL_SECS_Y    30      // number of seconds represented by y axis of waterfall
 #define WATERFALL_SECS_STEP 5       // graticule y axis steps of waterfall
 #define DT                  0.1     // time between real time graphing updates

These changes result in the following waterfall:

Screenshot 2023-07-25 at 10 48 16 PM

Based on the spectrogram from Octave above, I think this is close if not exactly correct. @drowe67, is it possible those Codec2 changes will end up breaking something else that's using the library?

tmiw commented 1 year ago

For comparison, here's with MODEM_STATS_NSPEC set to 2048:

Screenshot 2023-07-26 at 8 05 47 AM
drowe67 commented 1 year ago

@tmiw - thanks for looking into this one again. I must admit I get a bit confused with spectrograms, I never fully came to grips with the various trade offs, like screen resolution and fft rate (e.g. CPU).

The 1024 & 2048 point DFTs look a bit better, but I feel still lack the contrast of the Octave plot, or slower fading channel examples. The MPD plot doesn't look as "moth eaten" as the MPG and MPP examples. Having said that - I'm not exactly sure how deep the notches should be, and what color they should render too :thinking:

With a longer FFT (and time window), we should see more frequency resolution, but then again the signal is not stationary (as the channel is changing quickly). It's a bit like a camera with a slow shutter speed.

Is there any averaging code in freedv-gui (something like av = 0.9*av + 0.1*mag_dB)? That could be smoothing adjacent ffts so we don't see the notches that come and go quickly.

IIRC it's only freedv-gui that uses the spectrum code in modem_stats.c, it's one of those supporting chunks of C like the resamplers. Some of the codec2 CLI programs use other parts of modem_stats.

I also note we are using a FFT size of 2*MODEM_STATS_NSPEC, I think we could use a real fft (fftr) and halve that, reducing CPU by at least half. I'll add an issue to codec2.

drowe67 commented 1 year ago

Oh yes, and I think doubling the FFT size will double the CPU, as we appear to perform one fft every time nin samples are received. So it's a bit of trade off I guess.

DG9BFC commented 1 year ago

can i have my living room wall printed with that nice pattern ?!? :-) looks like a 70ties wallpaper hi hi dg9bfc sigi

tmiw commented 1 year ago

Is there any averaging code in freedv-gui (something like av = 0.9*av + 0.1*mag_dB)? That could be smoothing adjacent ffts so we don't see the notches that come and go quickly.

Yep. From src/pipeline/ComputeRfSpectrum.cpp:

    modem_stats_get_rx_spectrum(modemStatsFn_(), rx_spec, rx_fdm, numInputSamples);

    // Average rx spectrum data using a simple IIR low pass filter
    auto avMagPtr = getAvMagFn_();
    for(int i = 0; i < MODEM_STATS_NSPEC; i++) 
    {
        avMagPtr[i] = BETA * avMagPtr[i] + (1.0 - BETA) * rx_spec[i];
    }

Some more screenshots with various BETA values, WATERFALL_SECS_Y = 15 (to be able to better compare with Octave) and MODEM_STATS_NSPEC = 1024:

BETA = 0.25:

Screenshot 2023-07-27 at 5 16 57 PM

BETA = 0.50:

Screenshot 2023-07-27 at 5 18 10 PM

BETA = 0.75

Screenshot 2023-07-27 at 5 22 25 PM

BETA = 0.90

Screenshot 2023-07-27 at 5 24 01 PM

(Note: BETA is 0.95 in master and what the earlier screenshots used before I started tweaking this.)

Personally, something between 0.75 and 0.90 is probably best here as something closer to the latter will look pretty smeared but it's possible 0.95 was previously chosen for a specific reason too.

drowe67 commented 1 year ago

Nice work @tmiw - that's looking much better. BETA sets the freq response of a simple IIR low pass filter that's smoothing the spectrum "lines" between time steps. The reason for 0.95 is lost in history ... as I mentioned there was a fair bit of guess work when we wrote this 10 years (!) ago.

If we can keep MODEM_STATS_NSPEC to the codec2/master 512, even better, as the CPU load won't change, and no codec2 tweaks are required. Having said that, with a little FFT magic we can probably get 1024 points for the price of 512 because https://github.com/drowe67/codec2/issues/6

It would be good to regression check that AWGN & MPP & off air signals still look OK with your new BETA.

If you feel like it, the contrast might also be able to be tweaked, ie how dB is mapped to colour. IIRC there is some sort of AGC in there.

I'm happy for you to run with this and merge when you're ready, I think you've worked out what knobs to twiddle. If you still feel you need a codec2 tweak please raise a codec2 PR.

drowe67 commented 1 year ago

can i have my living room wall printed with that nice pattern ?!? :-) looks like a 70ties wallpaper hi hi dg9bfc sigi

Actually that is a good idea - FreeDV merch! Not sure about wall paper but we could maybe make some hats and t-shirts :thinking: I'll add it to the PLT agenda :slightly_smiling_face:

tmiw commented 1 year ago

If we can keep MODEM_STATS_NSPEC to the codec2/master 512, even better, as the CPU load won't change, and no codec2 tweaks are required. Having said that, with a little FFT magic we can probably get 1024 points for the price of 512 because drowe67/codec2#6

I think we might need to bump that up to 1024 for absolute best results but I think I got the PR I opened good enough that we can get by on 512 for now until that codec2 issue's worked on. The big issue is that things get pretty blocky if I shrink the waterfall history down to 10-15s instead of 30s (though it does make it easier to see the bands in the MPD signal), and I don't want to impact regular signals too badly in favor of the MPD case.

Anyway, I'll leave #487 open for a few days to make sure there are no major issues. @barjac, @Tyrbiter?

Tyrbiter commented 1 year ago

Just trying a version including this PR now. The spectrum display is quite different, faster, so will take some getting used to, it's what I normally look at.

I will see if I can look at some waterfall plots as I find on-air signals with different channel characteristics.

barjac commented 1 year ago

I will be testing this later on 60m. Noise looks crisper now.

DG9BFC commented 1 year ago

corporate identity :-) ... yes a t shirt with that pattern and order with your call sign printed on

barjac commented 1 year ago

In qso today: Screenshot_20230728_171008

tmiw commented 1 year ago

Seems pretty reasonable. I also pushed some changes to have the Y axis be a fixed number of pixels/second to avoid issues with the waterfall seemingly not scrolling quickly enough if you're interested in trying that too 👍