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

Add support for sending callsigns using RADE #783

Merged
merged 59 commits into from
Dec 27, 2024
Merged

Add support for sending callsigns using RADE #783

merged 59 commits into from
Dec 27, 2024

Conversation

tmiw
Copy link
Collaborator

@tmiw tmiw commented Dec 7, 2024

WIP PR to bring over the reliable_text library from codec2 and adapt it for RADE.

NOTE: requires #780 to be merged first. I merged that branch in here to make sure we're not also fighting bugs with EOO TX while implementing this PR.

@tmiw tmiw mentioned this pull request Dec 7, 2024
16 tasks
@tmiw
Copy link
Collaborator Author

tmiw commented Dec 7, 2024

@drowe67, so I'm pretty sure the TX side is correct based on the logs below. I'm not fully sure about the RX side, though. For instance, this run supposedly decoded with low BER but the decoded callsign is obviously not correct:

12:39:51 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:174: creating RADE text object
12:39:51 INFO /Users/mooneer/freedv-gui/src/main.cpp:2380: Setting callsign to K6AQ
12:39:51 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:684: generating RADE text string
12:39:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:355: generated bits: 0100010101111000001000101000100100000000000000000000000000011011001100000111011000110111101101001110011111111000
n_eoo_bits: 180
setting bits!
[-1.  1. -1. -1. -1.  1. -1.  1.]
...
 72 state: sync       valid: 1 1 25 Dthresh:     1.35 Dtmax12:     1.38     2.30 tmax:  596 fmax:  -0.10 uw_err: 0
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.775529, 3.779023
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -5.341875, 0.002470, amp: 5.341876
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.402584, -4.862893
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 1.032595, -5.844574, amp: 5.935091
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.357450, 3.748614
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -5.024745, 0.276595, amp: 5.032352
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.554029, 3.386225
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -4.907501, -0.118655, amp: 4.908936
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.696001, 4.581143
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -5.852825, 0.625890, amp: 5.886195
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 4.371028, 5.590434
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.862250, 7.043818, amp: 7.096396
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 4.261447, -4.336249
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 6.079489, -0.052893, amp: 6.079720
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -4.022218, -3.600053
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.298516, -5.389759, amp: 5.398019
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -4.681944, -1.843672
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -2.006961, -4.614307, amp: 5.031871
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 4.719862, -3.162938
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 5.573982, 1.100912, amp: 5.681662
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.917257, -3.007146
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.643546, -4.896292, amp: 4.938404
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 4.428773, -2.124363
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 4.633767, 1.629464, amp: 4.911919
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 4.889199, -2.186151
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 5.003027, 1.911343, amp: 5.355700
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.811704, -1.568797
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -1.585974, -3.804589, amp: 4.121918
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 5.455299, -2.610873
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 5.703645, 2.011313, amp: 6.047888
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -4.020313, 6.916108
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -7.733217, 2.047637, amp: 7.999717
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.908288, -2.733563
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.123549, -3.989392, amp: 3.991304
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -3.372199, -2.269004
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.780076, -3.988933, amp: 4.064493
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -1.788133, -2.813434
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.724997, -3.253799, amp: 3.333591
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.713071, -1.682328
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.728846, -3.108016, amp: 3.192332
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -1.622112, -2.353001
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.516816, -2.810830, amp: 2.857947
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.527061, -1.423358
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.780436, -2.793368, amp: 2.900342
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.064944, -2.175893
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.078453, -2.998724, amp: 2.999751
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -1.666388, -2.090050
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.299575, -2.656203, amp: 2.673043
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.265283, -2.542145
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.195771, -3.399364, amp: 3.404997
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -1.915202, -2.008861
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.066227, -2.774731, amp: 2.775521
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.528854, -2.042469
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.343926, -3.232413, amp: 3.250659
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.496720, -3.054840
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.394650, -3.925545, amp: 3.945333
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -1.469892, -3.582870
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 1.494101, -3.572842, amp: 3.872665
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -2.430099, 4.886643
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -5.173718, 1.737039, amp: 5.457533
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.157032, -0.138802
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.209186, 0.012890, amp: 0.209583
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.107731, -0.021630
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.091472, 0.060883, amp: 0.109881
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.059609, -0.004092
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.045044, 0.039257, amp: 0.059750
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.050095, 0.058800
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.006155, 0.077001, amp: 0.077246
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -0.040077, 0.112449
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.107852, 0.051175, amp: 0.119378
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -0.134685, -0.011243
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.087287, -0.103186, amp: 0.135153
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -0.058107, -0.069861
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.008312, -0.090487, amp: 0.090868
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.049075, -0.002345
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.036360, 0.033043, amp: 0.049131
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.013335, 0.062768
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.034954, 0.053813, amp: 0.064169
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -0.040595, 0.022309
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.044480, -0.012930, amp: 0.046321
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.004643, -0.015399
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.014172, -0.007606, amp: 0.016084
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.039180, 0.011544
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.019542, 0.035867, amp: 0.040845
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.030560, 0.035076
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.003193, 0.046412, amp: 0.046521
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.031346, 0.030395
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.000673, 0.043658, amp: 0.043663
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.019793, 0.033921
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.009990, 0.037981, amp: 0.039273
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.003318, 0.025458
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.015656, 0.020347, amp: 0.025673
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.002216, 0.010964
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.006185, 0.009320, amp: 0.011185
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.008534, -0.001192
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.006877, 0.005192, amp: 0.008617
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.020363, -0.000338
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.014638, 0.014160, amp: 0.020366
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.025838, 0.007693
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.012831, 0.023710, amp: 0.026959
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.036222, 0.025392
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.007658, 0.043567, amp: 0.044235
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.004711, 0.005703
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.000701, 0.007364, amp: 0.007397
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: -0.002343, 0.006805
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: -0.006469, 0.003155, amp: 0.007197
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.869280, 0.014924
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.604121, 0.625226, amp: 0.869408
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.007579, -0.156452
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.115987, -0.105269, amp: 0.156635
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:224: RX symbol: 0.207971, -0.157764
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: RX symbol rotated: 0.258613, 0.035502, amp: 0.261039
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:184: mean amplitude: 2.519175
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:196: BER est: 0.035714
12:40:06 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:256: rxCRC: 247, calcCRC: 2, decodedStr: 1*&BBBB

(Amplitude calculation is basically sqrt(sum(|v|) applied to each member of the amps array, i.e. each amp should equal 2.519175 above. Line 220 of rade_text.c is where the rotation and initial amps calculation happens, mean is taken and applied around line 169.)

Test procedure:

  1. Press Record in FreeDV and then PTT.
  2. Transmit for a few seconds, then push PTT again.
  3. Stop recording and then play back the recorded file with Tools-Start Play File - From Radio.

Maybe you'll be able to see something obvious that I missed?

@drowe67
Copy link
Owner

drowe67 commented Dec 7, 2024

Try:

  1. Plot the tx.wav file and make sure the EOO bit looks sensible compared to radae_tx.c, e.g. not 0 amplitude or grossly clipped.
  2. Add a little temp code to dump the IQ values to a .f32 file and plot the scatter diagram before and after rotation, e.g. in Octave s=load_f32('t.f32',1); plot(s(1:2:end),s(2:2:end),'+'); Should be 4 fairly clean balls.
  3. The RMS magnitude should be the distance of the center of each of the 4 balls from the origin.

(Amplitude calculation is basically sqrt(sum(|v|)

Should be sqrt(sum(|v|^2))/N), RMS = root - mean - square, for for complex numbers (assuming s[] is populated)

COMP s[N];
float sum_sq = 0.0;
for(int=0; i<N; i++)
  sum_sq += s[i].real*s[i].real + s[i].imag*s[i].imag;
mag = sqrt(sum_sq/N);

@drowe67
Copy link
Owner

drowe67 commented Dec 8, 2024

@tmiw - I fixed an error in (3) and added some C code to the comment ☝️

tmiw added 3 commits December 7, 2024 23:07
1. Add RadeTextTest to rule out any issues with freedv-gui.
2. Calculate RMS magnitude across all EOO bits, not just the ones used by RADE text.
@tmiw
Copy link
Collaborator Author

tmiw commented Dec 8, 2024

  1. Plot the tx.wav file and make sure the EOO bit looks sensible compared to radae_tx.c, e.g. not 0 amplitude or grossly clipped.

I ended up creating a RadeTextTest executable to hopefully isolate out as much of the audio handling as possible. There might still be an issue with scaling but it would be in RADE specific code and not somewhere else. 👍

Execute using the following:

(rade-venv) parallels@ubuntu-linux-2404:~/freedv-gui$ UT_ENABLE=1 ./build_linux.sh
...
(rade-venv) parallels@ubuntu-linux-2404:~/freedv-gui$ cd build_linux
(rade-venv) parallels@ubuntu-linux-2404:~/freedv-gui/build_linux$ PYTHONPATH=rade_src/ src/pipeline/RadeTextTest 
  1. Add a little temp code to dump the IQ values to a .f32 file and plot the scatter diagram before and after rotation, e.g. in Octave s=load_f32('t.f32',1); plot(s(1:2:end),s(2:2:end),'+'); Should be 4 fairly clean balls.

Original (pre-rotation):

plot_orig

After rotation:

plot_rot

(Note: I used -ROT45 instead of ROT45 as that got me lower BER. Unfortunately, still not low enough to proceed past LDPC decoding with the RadeTextTest script.)

  1. The RMS magnitude should be the distance of the center of each of the 4 balls from the origin.

After tweaking, it seems to match up with what Octave generates now, anyway:

00:16:55 INFO /home/parallels/freedv-gui/src/pipeline/rade_text.c:182: mean amplitude: 4.987538
00:16:55 INFO /home/parallels/freedv-gui/src/pipeline/rade_text.c:193: BER est: 0.214286

vs.

octave:33> d = load_f32("../../syms_rot.f32", 1)
...
octave:34> e = d(1:2:end) + j * d(2:2:end)
...
octave:35> rms(e)
ans = 4.9875

Generated symbol files if you want to analyze further: syms.f32.zip

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 8, 2024

I looked at the RADE code a bit more closely this morning and it looks like it was a problem with the TX side after all. The test application/ctest is now properly decoding, including with interleaving:

11: 09:54:47 INFO /home/parallels/freedv-gui/src/pipeline/rade_text.c:152: mean amplitude: 3.482183
11: 09:54:47 INFO /home/parallels/freedv-gui/src/pipeline/rade_text.c:163: BER est: 0.000000
11: 09:54:47 INFO /home/parallels/freedv-gui/src/pipeline/rade_text.c:231: rxCRC: 162, calcCRC: 162, decodedStr: K6AQ
11: 09:54:47 INFO /home/parallels/freedv-gui/src/pipeline/test/RadeTextTest.cpp:14: Callsign received: K6AQ
11:  11 state: search     valid: 1 0 25 Dthresh:     0.17 Dtmax12:     0.98     2.66 tmax:  196 fmax:   0.00

I'll probably do some code cleanup and then do testing with the full freedv-gui stack.

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 8, 2024

RADE RX callsign reporting is working :)

Screenshot 2024-12-08 at 10 15 20 AM

@drowe67
Copy link
Owner

drowe67 commented Dec 16, 2024

@tmiw that seems better, suggest you also try the other AWGN suggestion above (edited):

It's fine to test in AWGN (e.g. around 2dB) - it should be able to correct all errors at about 4% raw BER (maybe more depending on the code rate). You should see significant uncoded errors in the AWGN channel as the SNR drops. I'd start with AWGN, and make sure that does sensible things first. As a known good example, try modifying the rade ctest to be AWGN and drop the SNR, watch the uncoded BER climb.

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 16, 2024

@tmiw that seems better, suggest you also try the other AWGN suggestion above (edited):

It's fine to test in AWGN (e.g. around 2dB) - it should be able to correct all errors at about 4% raw BER (maybe more depending on the code rate). You should see significant uncoded errors in the AWGN channel as the SNR drops. I'd start with AWGN, and make sure that does sensible things first. As a known good example, try modifying the rade ctest to be AWGN and drop the SNR, watch the uncoded BER climb.

I dropped --No to -14, producing the following ch output with AWGN:

ch: SNR3k(dB):    -2.91  C/No....:    31.86
ch: peak.....: 22485.21  RMS.....:  7813.96   CPAPR.....:  9.18 
ch: Nsamples.:   176640  clipped.:     0.00%  OutClipped:  0.06%

Across multiple runs, the highest raw BER I was able to get was 0.036:

09:08:36 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:180: mean amplitude: 4.293107
09:08:36 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:190: Estimated BER: 0.000000
09:08:36 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits:      112 Terr:      4 BER: 0.036
09:08:36 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits:     56 Terr:      0 BER: 0.000
09:08:36 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:289: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
09:08:36 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
09:08:36 INFO /Users/mooneer/freedv-gui/src/main.cpp:1914: Adding callsign ZZ0ZZZ @ SNR 0, freq 14236000 to PSK Reporter.

The other runs for reference:

09:09:48 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:180: mean amplitude: 4.352207
09:09:48 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:190: Estimated BER: 0.428571
09:09:48 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits:      112 Terr:      8 BER: 0.071
09:09:48 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits:     56 Terr:     15 BER: 0.268
09:10:46 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:180: mean amplitude: 4.350485
09:10:46 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:190: Estimated BER: 0.464286
09:10:46 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits:      112 Terr:      2 BER: 0.018
09:10:46 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits:     56 Terr:      3 BER: 0.054
09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:180: mean amplitude: 4.385533
09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:190: Estimated BER: 0.267857
09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits:      112 Terr:      0 BER: 0.000
09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits:     56 Terr:      7 BER: 0.125
09:13:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:180: mean amplitude: 4.518073
09:13:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:190: Estimated BER: 0.000000
09:13:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits:      112 Terr:      2 BER: 0.018
09:13:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits:     56 Terr:      0 BER: 0.000
09:13:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:289: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
09:13:30 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
09:13:30 INFO /Users/mooneer/freedv-gui/src/main.cpp:1914: Adding callsign ZZ0ZZZ @ SNR 0, freq 14236000 to PSK Reporter.
09:14:27 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:180: mean amplitude: 4.581088
09:14:27 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:190: Estimated BER: 0.089286
09:14:27 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits:      112 Terr:      3 BER: 0.027
09:14:27 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits:     56 Terr:      1 BER: 0.018
09:14:27 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:289: rxCRC: 78, calcCRC: 75, decodedStr: VZ0ZZZ

So yeah, it looks like we're able to correct down to ~4% as you mentioned.

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 20, 2024

Was there anything else still pending for this PR? We can open another one if we need to make code changes for @Tyrbiter's observation.

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 20, 2024

Oops, forgot to tag @drowe67 for the above question.

@Tyrbiter
Copy link

It appears to work OK, so don't hold fire on my account, not actually sure what is happening and if there really is a buffering problem.

@drowe67
Copy link
Owner

drowe67 commented Dec 21, 2024

@tmiw - there's still some pretty obvious errors above, e.g.

09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits: 112 Terr: 0 BER: 0.000
09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits: 56 Terr: 7 BER: 0.125

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 22, 2024

@tmiw - there's still some pretty obvious errors above, e.g.

09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:219: Raw Tbits: 112 Terr: 0 BER: 0.000
09:12:15 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:221: Coded Tbits: 56 Terr: 7 BER: 0.125

I added some logic in 20a9c9e to output the TX and RX floats to files, which I've been passing to eoo_ber.py. So far, whatever that script is generating seems to line up with what the C code is doing to calculate raw BER. Example:

14:55:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:206: mean amplitude: 4.352175
14:55:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:216: Estimated BER: 0.553571
14:55:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:233: Raw Tbits:      112 Terr:      8 BER: 0.071
14:55:30 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:235: Coded Tbits:     56 Terr:     15 BER: 0.268
(radae-venv) mooneer@macaron build_osx % mv src/FreeDV.app/Contents/Resources/*.f32 . &&    
cmdand> python3 rade_src/eoo_ber.py tx_bits.f32 rx_bits.f32
frame received! BER:  0.07
EOO frames  received: 1 n_ok_frames: 0

For coded BER, is that always going to be lower than raw BER, or do those have no correlation with each other? FWIW the current coded BER calculation is as follows:

        // Calculate coded BER.
        int bitsCoded = 0;
        int errorsCoded = 0;
        for (int index = 0; index < LDPC_TOTAL_SIZE_BITS / 2; index++)
        {
            bitsCoded++;
            int err = LastLDPCAsBits[index] != output[index];
            if (err)
            {
                errorsCoded++;
            } 
        }

with LastLDPCAsBits populated in rade_text_generate_tx_string() as follows:

    memcpy(&tmpbits[0], &ibits[0], LDPC_TOTAL_SIZE_BITS / 2);
    memcpy(&tmpbits[LDPC_TOTAL_SIZE_BITS / 2], &pbits[0], LDPC_TOTAL_SIZE_BITS / 2);
    memcpy(LastLDPCAsBits, tmpbits, LDPC_TOTAL_SIZE_BITS);

@drowe67
Copy link
Owner

drowe67 commented Dec 22, 2024

For coded BER, is that always going to be lower than raw BER, or do those have no correlation with each other? FWIW the current coded BER calculation is as follows:

The idea of FEC is to correct errors, not introduce them. So beneath a certain threshold (around 8% for a rate 0.5 LPDC code), the coded BER < uncoded BER. Getting coded errors when there are no uncoded errors should be impossible.

Not sure what all those arrays are doing in your code. There are many examples of BER tests with LDPC in libcodec2. You compare the tx bits to the rx bits. I usually start with a fixed test frame known to both the Tx and Rx.

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 24, 2024

OK, I think I figured out the discrepancy. With the following AWGN setup:

ch: SNR3k(dB):    -1.86  C/No....:    32.91
ch: peak.....: 22485.85  RMS.....:  7863.98   CPAPR.....:  9.13 
ch: Nsamples.:   174400  clipped.:     0.00%  OutClipped:  0.02%

I got the following runs:

14:42:01 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.089860
14:42:01 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.000000
14:42:01 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     39 BER: 0.217
14:42:01 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     21 BER: 0.187
14:42:01 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      0 BER: 0.000
14:42:01 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:334: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
14:42:01 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
14:42:01 INFO /Users/mooneer/freedv-gui/src/main.cpp:1923: Reporting callsign ZZ0ZZZ @ SNR 0, freq 14236000 to reporting services.
14:43:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.351367
14:43:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.000000
14:43:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     43 BER: 0.239
14:43:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     21 BER: 0.187
14:43:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      0 BER: 0.000
14:43:51 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:334: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
14:43:51 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
14:43:51 INFO /Users/mooneer/freedv-gui/src/main.cpp:1923: Reporting callsign ZZ0ZZZ @ SNR 0, freq 14236000 to reporting services.
15:52:35 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.256936
15:52:35 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.035714
15:52:35 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     32 BER: 0.178
15:52:35 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     18 BER: 0.161
15:52:35 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      0 BER: 0.000
15:52:35 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:334: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
15:52:35 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
15:52:36 INFO /Users/mooneer/freedv-gui/src/main.cpp:1923: Reporting callsign ZZ0ZZZ @ SNR 0, freq 14236000 to reporting services.
15:53:32 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.326820
15:53:32 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.000000
15:53:32 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     36 BER: 0.200
15:53:32 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     21 BER: 0.187
15:53:32 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      0 BER: 0.000
15:53:32 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:334: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
15:53:32 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
15:53:32 INFO /Users/mooneer/freedv-gui/src/main.cpp:1923: Reporting callsign ZZ0ZZZ @ SNR 0, freq 14236000 to reporting services.
15:57:34 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 3.887419
15:57:34 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.500000
15:57:34 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     43 BER: 0.239
15:57:34 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     27 BER: 0.241
15:57:34 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      5 BER: 0.089

(I added an additional BER calculation for the entire EOO--not just the 112 bits that are actually used--to at least make sure "raw" errors isn't higher than the EOO errors.)

The idea of FEC is to correct errors, not introduce them. So beneath a certain threshold (around 8% for a rate 0.5 LPDC code), the coded BER < uncoded BER. Getting coded errors when there are no uncoded errors should be impossible.

Seems to at least be doing that now. I'm guessing there was a calculation error somewhere along the line before that got fixed with today's commits.

Not sure what all those arrays are doing in your code. There are many examples of BER tests with LDPC in libcodec2. You compare the tx bits to the rx bits. I usually start with a fixed test frame known to both the Tx and Rx.

The arrays are mainly to store the generated LDPC bits/floats for later comparison. There is indeed a known sequence (the bits needed to encode the "callsign" ZZ0ZZZ, the latter of which is injected by the test framework).

@tmiw tmiw mentioned this pull request Dec 24, 2024
@tmiw
Copy link
Collaborator Author

tmiw commented Dec 25, 2024

@drowe67, here's some additional testing with -14 passed to ch, resulting in the following output from the tool:

ch: SNR3k(dB):    -2.66  C/No....:    32.11
ch: peak.....: 22835.08  RMS.....:  8050.97   CPAPR.....:  9.06 
ch: Nsamples.:   168480  clipped.:     0.00%  OutClipped:  0.06%

Most runs don't decode a callsign but the number of error bits for coded BER is consistently lower than raw BER:

17:06:11 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.084727
17:06:11 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.071429
17:06:11 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     28 BER: 0.156
17:06:11 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     19 BER: 0.170
17:06:11 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      0 BER: 0.000
17:06:11 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:334: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
17:06:11 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
17:06:11 INFO /Users/mooneer/freedv-gui/src/main.cpp:1923: Reporting callsign ZZ0ZZZ @ SNR 0, freq 14236000 to reporting services.
17:07:08 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.218708
17:07:08 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.000000
17:07:08 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     35 BER: 0.194
17:07:08 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     18 BER: 0.161
17:07:08 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:      0 BER: 0.000
17:07:08 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:334: rxCRC: 78, calcCRC: 78, decodedStr: ZZ0ZZZ
17:07:08 INFO /Users/mooneer/freedv-gui/src/freedv_interface.cpp:114: FreeDVInterface::OnRadeTextRx_: received ZZ0ZZZ
17:07:08 INFO /Users/mooneer/freedv-gui/src/main.cpp:1923: Reporting callsign ZZ0ZZZ @ SNR 0, freq 14236000 to reporting services.
17:08:04 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.225422
17:08:04 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.375000
17:08:04 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     35 BER: 0.194
17:08:04 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     19 BER: 0.170
17:08:04 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:     17 BER: 0.304
17:09:05 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.225407
17:09:05 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.607143
17:09:05 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     35 BER: 0.194
17:09:05 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     19 BER: 0.170
17:09:05 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:     12 BER: 0.214
17:10:00 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:210: mean amplitude: 4.332929
17:10:00 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:220: Estimated BER: 0.589286
17:10:00 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:238: EOO Tbits:      180 Terr:     43 BER: 0.239
17:10:00 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:239: Raw Tbits:      112 Terr:     24 BER: 0.214
17:10:00 INFO /Users/mooneer/freedv-gui/src/pipeline/rade_text.c:241: Coded Tbits:     56 Terr:     15 BER: 0.268

Let me know if there's any additional testing you'd like me to do or if we can go ahead and close this PR out.

@drowe67
Copy link
Owner

drowe67 commented Dec 25, 2024

@tmiw look like it's headed in the right direction, but it's unusual (very low probability), that the FEC code will work at 17% raw errors. To get a feel for the expected performance try:

cd codec2/octave
octave-cli
octave:3> ldpcut; test3_curves("HRA_56_56.txt")

I'm guessing you are using HRA_56_56.txt. This simulation indicates coded BER knee between 8-10% raw BER, as I mentioned above.

Just to confirm:

  1. The payload data d (56 bits I assume) is FEC encoded to a codeword c (112 bits).
  2. c is sent over the channel to get c_hat.
  3. c_hat is FEC decoded to obtain the decoded data d_hat (56 bits)
  4. The raw BER is the number of errors in c compared to c_hat (112 bits compared).
  5. The coded BER is the number of errors in d compared to d_hat (56 bits compared).

@tmiw
Copy link
Collaborator Author

tmiw commented Dec 27, 2024

@drowe67:

I'm guessing you are using HRA_56_56.txt. This simulation indicates coded BER knee between 8-10% raw BER, as I mentioned above.

Correct, we're using HRA_56_56.

Just to confirm:

  1. The payload data d (56 bits I assume) is FEC encoded to a codeword c (112 bits).
  2. c is sent over the channel to get c_hat.

What's done for encoding (rade_text_generate_tx_string() in rade_text.c):

flowchart TB
    step1["Encode callsign into 6 bit character set"]
    step2["Calculate CRC8"]
    step3["LDPC encode"]
    step3["Concatenate ibits and pbits together"]
    step4["Interleave bits"]
    step5["Convert bits to symbols"]
    step6["Concatenate additional symbols to fill EOO block"]
    step1 --> step2
    step2 --> step3
    step3 --> step4
    step4 --> step5
    step5 --> step6
Loading

The interleaved bits are converted to symbols as follows (based on what I found in codec2 ofdm.c):

Bit Sequence Symbol
00 1.0 + 0.0i
01 0.0 + 1.0i
10 0.0 - 1.0i
11 -1.0 + 0.0i

And to fill out the EOO block, we send repeated 10 (i.e. 0.0 - 1.0i).

  1. c_hat is FEC decoded to obtain the decoded data d_hat (56 bits)

On the decode side (rade_text_rx() in rade_text.c):

flowchart TB
    step1["Deinterleave symbols"]
    step2["Calculate RMS magnitude of received symbols"]
    step3["Convert symbols to LLRs"]
    step4["LDPC decode"]
    step5{"Estimated BER from LDPC decoder < 0.2?"}
    step6["Drop received callsign"]
    step5a["Calculate CRC8 of received callsign"]
    step5b{"Calculated CRC8 == received CRC8?"}
    step5b1["Convert callsign to ASCII"]
    step5b2["Pass callsign to higher level code"]
    step5c["Drop received callsign"]
    step1 --> step2
    step2 --> step3
    step3 --> step4
    step4 --> step5 
    step5 -- Yes -->step5a
    step5a --> step5b
    step5b-- Yes --> step5b1
    step5b1 --> step5b2
    step5b-- No --> step5c
    step5-- No -->step6
Loading
  1. The raw BER is the number of errors in c compared to c_hat (112 bits compared).

Correct (LastEncodedLDPC array vs. symbols passed into rade_text_rx()).

  1. The coded BER is the number of errors in d compared to d_hat (56 bits compared).

Correct (LastLDPCAsBits array vs. bits returned in the "LDPC decode" step above).

Note on the BER calculation: it appears that the formula for BER calculation is basically (expected * actual) < 0 (i.e. detect sign changes). However, this doesn't seem to work well given that 0 is possible along with negative and positive values. Though that would cause BERs to be higher if corrected for, not lower.

BTW I ran the AWGN test 30 times with ch - - --No -14 and only got a decoded callsign twice (once at 0.161 raw BER and once at 0.214 raw BER), or about 7% of the time. This might still not be in line with what's expected but I figured I'd put that out there. I've attached the raw data from the runs if you'd like to do more analysis: vals.csv

@drowe67
Copy link
Owner

drowe67 commented Dec 27, 2024

@tmiw - thanks for that detailed explanation. The val.csv values make sense, just the occasional decode at at such a high raw BER. So I'm good to merge this and will merge drowe67/radae#35.

I'm not sure how useful the LDPC based BER estimate is, it's probably based on the # of parity checks that match.

@tmiw tmiw merged commit 93770ac into v2.0-dev Dec 27, 2024
4 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.

3 participants