Guenael / rtlsdr-wsprd

WSPR daemon for RTL receivers
GNU General Public License v3.0
112 stars 32 forks source link

Less decodes than WSJT-X #101

Closed dforsi closed 2 years ago

dforsi commented 2 years ago

The .c2 file in 211212_2142.zip was saved by WSJT-X 2.5.2 which decodes the following 3 signals from the corresponding .wav file (it doesn't read back the .c2 file):

UTC    dB   DT     Freq     Drift  Call          Grid    dBm   km
2142  -29   0.6    0.001424    0   DL6OBU        JO43     23   1131
2142  -16   0.9    0.001493    0   M0ICR         IO91     27   1245
2142  -28   1.3    0.001598    0   2E0DYH        JO01     37   1147

but rtlsdr-wsprd 0.4.2 decodes only one signal:

        SNR      DT        Freq Dr    Call    Loc Pwr
Spot : -15.48  -0.12   0.001493  0   M0ICR   IO91 27

I made this simple change to just skip the header skip-26-bytes.txt but it would be nice to read the dial frequency from the header and use it in the output.

dforsi commented 2 years ago

Strangely, copying the command shown by WSJT-X in its status line gets the same decode as rtlsdr-wsprd:

$ /usr/bin/wsprd -C 500 -o 4 -d 211212_2142.c2
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
<DecodeFinished>

Removing "-C 500" gets one more decode:

$ /usr/bin/wsprd -o 4 -d 211212_2142.c2
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
2142 -29  1.1   7.040198  0  2E0DYH JO01 37 
<DecodeFinished>

I'm attaching the .wav file 211212_2142.zip

Guenael commented 2 years ago

@dforsi Hi,

Ok, there are many things to discuss on your previous comment. Initially, I started to write:

  1. Interesting report! I was on my plans to update rtlsdr-wsprd to the latest version of wsprd wrote by K9AN (included in lib/wsprd of wsjtx).

    There are some improvements I guess, but the fact you get different reports between wsjt-x and the latest version of wsprd, shows that wsjt-x still use the Fortran code, and not the C code. It could be interesting to double check this point by watching the code.

    Initially, my goal was to glue two projects to offer a very simple tool to deploy on a cheap device, to increase the number of reports on VHF/UHF bands. But most of peoples try to use it with the direct sampling option for the HF band ^^ (not a great device for HF bands BTW)

  2. But I started to look at your sample, and I cannot understand how you can decode this sample... This sample is a .wav file, with a single channel, and a sampling rate of 12000 sps. rtlsdr-wsprd can only process IQ files (stereo), at 375 sps. Did you send the right file in your Zip? If you can decode a some spots using this header skip method, it's fun, and it's only because of some aliasing phenomena, and because WSPR is a robust protocol. But it should not work. Or I'm missing something on your comment/feedback.

LMK!!

Guenael commented 2 years ago

Hum... I missed the first Zip, with the .c2 file. I will take a look :) And I will use your patch to import .c2 files, but with another option to keep the simple .iq file format available.

Guenael commented 2 years ago

@dforsi Ahhh, another thing to check on your side. wsprd can use a hash file, and this file include your previous decoded stations. Reusing entries stored can ease the decoding of very weak signals, because it can search them specifically (it's a bit cheating, you know what you are looking for :D ) That could explain the difference. Try to locate and delete this file to check if there is any difference.

mkarliner commented 2 years ago

I have a suspicion that I'm see the same effect of different numbers of spots, but it's hard to check. My method is to either run rtlsdr-wsprd on the Pi or rtl_tcp pipe to gqrx to WJTX in the shack, so the hardware is the same. Trouble is, here in my very urban area, consecutive results are not consistent enough to be sure.

Guenael commented 2 years ago

I will update to the latest version of wsprd back-end, but on the decoder part, that's all I can do. I don't want to play with the decoder itself, too many dragons... WSPR should be received within +/-200 Hz, and my FIR CIC compensation filter add this constrain, I can enlarge the BW, if you want make a try (on a side branch). But when you load some samples from external files, this FIR filter in not used.

Guenael commented 2 years ago

@dforsi the command line with -o option (ex. $ /usr/bin/wsprd -o 4 -d 211212_2142.c2) provide additional depth using this Fortran function osdwspr. I will not include this file to this project, out of scope. But it's technically possible to build a similar project with the Fortran files.

Guenael commented 2 years ago

@dforsi Could you upload the content of your hashtable.txt file? (from wsjt-x)

dforsi commented 2 years ago

Thank you for you explanation. From the --help of wsprd about the -o option ( -o n (0<=n<=5), decoding depth for OSD, default is disabled) it isn't clear that it is using the Fortran code.

Here is my hashtable.txt anyway.

BTW, initially I passed the wrong arguments when running wsprd, this explains the differences in my second comment to this issue. With the same arguments copied form the status line of wsjtx, wsprd decodes the same signals that I can see in the GUI and both the .wav file and the .c2 give the same decodes, so the differences with rtlsdr-wsprd are explained by the different code bases:

$ /usr/bin/wsprd -C 500 -o 4 -d -a /home/daniele/.local/share/WSJT-X/ -f 7.038600 /home/daniele/.local/share/WSJT-X/save/211212_2142.c2
2142 -29  0.6   7.040024  0  DL6OBU JO43 23 
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
2142 -28  1.3   7.040198  0  2E0DYH JO01 37 
<DecodeFinished>

The status line is image

Guenael commented 2 years ago

@dforsi OK, I got it, it's related to the 'a priori' decoding. Without your hashtable, you will only got 1 entry, and with the hashtable, you will get 3.

> ./wsprd -C 500 -o 4 -d -f 7.038600 211212_2142.c2
2142 -29  0.6   7.040024  0  DL6OBU JO43 23 
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
2142 -28  1.3   7.040198  0  2E0DYH JO01 37 
<DecodeFinished>

> rm hashtable.txt 
rm: remove regular file 'hashtable.txt'? y

> ./wsprd -C 500 -o 4 -d -f 7.038600 211212_2142.c2
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
<DecodeFinished>

And if you remove -o option, the decoder will not find your 2 additional spots, even with the hashtable.

> ./wsprd -C 500 -d -f 7.038600 211212_2142.c2
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
<DecodeFinished>

> ./wsprd -C 500 -o 4 -d -f 7.038600 211212_2142.c2
2142 -29  0.6   7.040024  0  DL6OBU JO43 23 
2142 -15  0.9   7.040093  0  M0ICR IO91 27 
2142 -28  1.3   7.040198  0  2E0DYH JO01 37 
<DecodeFinished>

Some details about this option and function:

https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/lib/wsprd/wsprd.c#l853

case 'o':  //use ordered-statistics-decoder
    ndepth=(int) strtol(optarg,NULL,10);
    break;

https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/lib/wsprd/wsprd.c#l1355

if( (ndepth >= 0) && not_decoded ) {
    for(i=0; i<162; i++) {
        fsymbs[i]=symbols[i]-128.0;
    }
    t0 = clock();
    osdwspr_(fsymbs,apmask,&ndepth,cw,&nhardmin,&dmin); // <<< THIS FUNCTION
    tosd += (float)(clock()-t0)/CLOCKS_PER_SEC;

https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/lib/wsprd/wsprd.c#l47

extern void osdwspr_ (float [], unsigned char [], int *, unsigned char [], int *, float *);

https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/lib/wsprd/osdwspr.f90#l1

subroutine osdwspr(ss,apmask,ndeep,cw,nhardmin,dmin)

Nothing I can do, but you seem very motivated to re-write this function in plain C ;)

On my side, I will not go there. Fighting for 3-4 extra dB was not the goal of this project. -26dB is way enough for me and 'a priory' decoding is a bit like cheating. But learning and testing various strategy is super interesting!

73

Guenael commented 2 years ago

If you want to increase you detection ratio with wsjtx, you can take all the entries on WSPRnet, build you hastable, and replace your original file ;)