Skip to content

Conversation

@drowe67
Copy link
Owner

@drowe67 drowe67 commented Dec 9, 2022

Building up -5dB MPP waveforms as per FreeDATA-002 Milestone 2.

  1. datac4, 87 bit/s payload, -8dB AWGN, -4dB MPP, 4 carriers
  2. datac13 (signalling), 68 bit/s payload, -10dB AWGN, -4dB MPP, 3 carriers
  3. Bonus datac5, 1700 bits/s payload, 7dB MPP, 2200 Hz (Octave only).
  4. Refactoring of C and Octave ofdm code, e.g. handling "ones stuffing" better for variable code rates.
  5. Bonus experimental work with FSK on MPP, very early days, not ready for real world yet
  6. Helper function and notes for UW thresholds ofdm_determine_bad_uw_errors(Nuw)
  7. modem waveform spreadsheet automagically calculates Np and Nuw for datac4 & datac13.
ofdm_ldpc_tx('test_datac4.raw','datac4',1,-4,'mpp','bursts',20);
ofdm_ldpc_rx('test_datac4.raw','datac4','packetsperburst',1);
Raw BER..: 0.1065 Tbits: 30080 Terrs:  3203 SNR3k: -4.47
Coded BER: 0.0000 Tbits:  8960 Terrs:     0
Coded PER: 0.0000 Pckts:    20 Perrs:     0 Npre: 17 Npost: 3

First pass C Tx & Rx:

./src/ofdm_mod --mode datac4 --in /dev/zero --testframes 1 --verbose 1 --ldpc --bursts 3 > test_datac4.raw
./src/ofdm_demod --mode datac4 --in test_datac4.raw --out /dev/null --testframes --ldpc --verbose 2 --packetsperburst 1

TODO:

  1. refactor zero-stuffing to change code rate into ldpc.m, add unit test
  2. initial C port of datac4, datac13
  3. datac4 scatter diagram generated by ofdm_ldpc_rx doesn't look right with Octave or C Tx and no noise.
  4. Consider refactoring zero stuffing C code to move data_bits_per_frame into ofdm_config code, or raise an issue/further work PR.
  5. first pass ctests for datac4, datac13 and Octave<->C port
  6. Where to put input filter in Octave and C (e.g. inside ofdm_rx function)? In core ofdm.c acquisition and demod functions (needs to be in both).
  7. Retune acquistion with filter in place.
  8. PAPR/clipper tuning & check_comp.sh ctest
  9. Dial up noise for ctests when filter implemented.
  10. Decide if we should C port datac5 (it's just 2dB above datac1, not quite 2x throughput bit rate) Not for now, as we are not satisfied with mode design - would rather a larger increment in throughput bit rate & SNR.
  11. OTA unit testing of new waveforms Achieved by early integration into FreeDATA.
  12. README_data.md update, update script that generates PER curves.
  13. Log all further work items somewhere
  14. Optional : check bad_uw_errors thresholds for other raw data modes now we have ofdm_determine_bad_uw_errors(Nuw)
  15. Optional or future work: make data ctests burst mode, streaming data isn't of much use
  16. Optional: refactor LDPC_PROT to be non 2020 specific, e.g. LDPC_STUFF_ONES
  17. Optional or Further work: move operating point and throughput bit rate of datac5 up a bit, e.g. with slightly higher code rate
  18. Further work: Can input rx filters help other modes?
  19. Further work: does input BPF add appreciably to CPU load?
  20. Further work: "key clicks" at start and end of burst. This is wideband energy that may interfere slightly with other users. A little tapering of the start of pre-amble, end of postamble might be useful, so it's not such a sharp transition.
  21. Further work: explore wider (high Nc) at low SNRs, e.g. diversity, lower code rate, will sync hang on?

@drowe67 drowe67 changed the title Prototype datac4 and datac5 modes Prototype datac4 and datac5 and low FSK/MPP modes Dec 11, 2022
@drowe67
Copy link
Owner Author

drowe67 commented Dec 11, 2022

With the right configuration, the FSK modem can handle MPP channels OK. I think the long preamble helps with burst acquisition, as it rides over fades. It's early days, this is with a very long codeword (10's of seconds), and it doesn't cope well with bursts close together (small --delay), and isn't very efficient due to the long preamble.

Here is 25 bits/s payload 4FSK at -9 dB SNR on MPP:

cd codec2/build_linux/src
~/codec2/build_linux/src dr-datac4 $ ./freedv_data_raw_tx --Rs 25 --shift 50 -a 8000 --testframes 10 --bursts 10 -m 4 FSK_LDPC /dev/zero - | ./ch - - --No -14 --ssbfilt 1 --freq -10 --mpp --fading_dir ../unittest/ |  ./freedv_data_raw_rx --Rs 25 --shift 50 -m 4 --mask 50 --testframes -v --fsk_lower 950 --fsk_upper 1250 FSK_LDPC - /dev/null
<snip>
mark:space: 0.38 SNR offset: -4.16
ch: SNR3k(dB):   -12.90
Coded FER: 0.0000 Tfrms:    10 Tfers:     0

The offset accounts for the error in the SNRdB from ch due to the "off time" of the burst so the actual SNR is -12.90 + 4.16 = -8.9 dB. On AWGN it falls over at about -15dB.

Option to specific LDPC code. Shorter codewords don't work as well:

./freedv_data_raw_tx --delay 2000 --code HRA_112_112 --Rs 25 --shift 50 -a 8000 --testframes 20 --bursts 20 -m 4 FSK_LDPC /dev/zero - | ./ch - - --No -14 --mpg --ssbfilt 1 --freq -10 --fading_dir ../unittest/ |  ./freedv_data_raw_rx --code HRA_112_112 --Rs 25 --shift 50 -m 4 --mask 50 --testframes -v --fsk_lower 950 --fsk_upper 1250 FSK_LDPC - /dev/null
mark:space: 0.81 SNR offset: -0.90
ch: SNR3k(dB):    -9.60  C/No....:    25.17
Coded FER: 0.0000 Tfrms:    15 Tfers:     0

@drowe67 drowe67 changed the title Prototype datac4 and datac5 and low FSK/MPP modes Prototype datac4 and datac5 modes and low rate FSK/MPP Dec 11, 2022
@DJ2LS
Copy link
Contributor

DJ2LS commented Dec 28, 2022

@drowe67 here are some payload requirements, which are needed for the actual protocol of FreeDATA- specially the signalling frames have some limitations:

FreeDATA has two types of signalling frames.

  • INIT
    • Payload at least 14Bytes+2Bytes CRC (codec2)
    • transmission length doesn't matter that much. 2-3 seconds would be okay.
    • This mode is used for opening a data channel for example or sending beacons.
  • ACK/NACK
    • Payload at least 5Bytes + 2Bytes CRC (codec2)
    • transmission length matters, about 1 - 1,5 Second is needed
    • used for ACK bursts while an ongoing transmission
    • Transmission length has direct impact on overall transmission speed.
  • PAYLOAD/DATA
    • Used for data transmission
    • Transmission length about 4-6 seconds

@drowe67
Copy link
Owner Author

drowe67 commented Dec 29, 2022

Thanks @DJ2LS, a couple more thoughts:

  1. Maybe would add PAYLOAD to the frames used by FreeDATA. It's nice if these are about 4 seconds long, because multipath.
  2. Perhaps the INIT and PAYLOAD could use the same physical layer modes, given the protocol is not sensitive to the INIT transmission time.
  3. We want ACK/NACK to operate at or below the current payload mode SNR on AWGN and multipath channels. This can be a challenge due to the short duration. Making them wider in frequency might help.
  4. At some SNR/bit rate, we will no longer be able to fit 7 bytes into a 1 second ACK/NACK packet. An alternative definition might the ratio of the PAYLOAD to ACK/NACK duration should be 4. For example at very load SNRs/bit rates it could be 8 second payload, 2 second ack/nak - that will keep the protocol efficiency about the same
  5. Might be time to think about our data mode naming convention, datac0 stands for data candidate 0. Even the term "mode" came from the streaming FreeDV naming system, I think "levels" are used by some of other HF data systems.

@DJ2LS
Copy link
Contributor

DJ2LS commented Dec 29, 2022

@drowe67 I updated the list.

  1. Yes, specially datac4, prototyped here, would be a good candidate for this. It could be used as init mode and also as data mode.

  2. One point is, we should stay below 500Hz, so we can cover all bands and laws. We could also do some tests to see how mode is affecting the protocol. Maybe a 1.5 seconds burst with about 250Hz bandwidth would also fit and data rate doesn't drop too much on high SNR.

  3. Problem here is, I'm switching between active modes and turning them "on/off" like the protocol needs them for saving CPU power. Introducing another signalling mode at this level might cause instabilities and SNR also changes. So I tend to prefer just one signalling mode for ACK/NACK. But maybe we can find a good tradeoff? At least I try to keep this level simple for avoiding problems by decoding/mode complexity. HF channels already causing a lot of different use-cases, weird behavior and complexity which need to be covered by the protocol.

  4. we could start with a small table

@drowe67
Copy link
Owner Author

drowe67 commented Dec 29, 2022

@DJ2LS it's clear we have built up a lot of experience that can be used for future iterations. It might be useful to write down some use cases and develop some requirements and a road map going forward. That will also be useful to guide contributions by others. A good start would be what SNRs we want to cover in the next iteration, the waveform designs can be derived from that.

Re (4) the requirement here might be CPU load, design use case might be "two parallel receivers at any one time". Re CPU (i) we could look at vectorisation (ii) once we have started a connection, the acquisition range can be narrowed and CPU will drop. We just need to track slow freq drift (common with older radios).

@DJ2LS
Copy link
Contributor

DJ2LS commented Dec 29, 2022

Agree, @drowe67

I suggest let's use this PR for roadmap. We could place it to the first entry and edit on changes.

Re
i) yes I remember this topic. But didn't find the time yet for this. Maybe @tmiw is interested in supporting here?

ii) Interesting, After i) this could be the next step. Also your suggested reduction of LDPC iterations could be considered.

I'll think about a road map and will make some suggestions the next days.

@tmiw
Copy link
Collaborator

tmiw commented Dec 30, 2022

I actually haven't played with the freedv_data_raw_* applications yet, so I went ahead and tried it out with datac3 (this PR doesn't work with datac4 yet). Seems that most of the CPU is being taken by the clipper/BPF:

Screenshot 2022-12-30 at 3 34 28 AM

(I used ./freedv_data_raw_tx datac3 ~/Downloads/schematic-feathers3.pdf test for the command line.)

It might be worth revisiting #326, anyway. IIRC it mostly worked (and didn't sound different OTA from what I remember) but a few ctests failed due to a few of the bytes being different. However, that PDF is also ~150 KB, which I'm not sure is a realistic size for HF.

@DJ2LS
Copy link
Contributor

DJ2LS commented Dec 30, 2022

Here's the old discussion regarding to this topic: https://github.com/DJ2LS/FreeDATA/discussions/119

Most work might be needed for RX I think 🤔

@drowe67
Copy link
Owner Author

drowe67 commented Dec 30, 2022

Yep it's the Rx side and specifically acquisition that we had in mind. So its CPU load with no modem signal (e.g. just noise for ch). Possibly just some vectorisation on the inner loop DSP.

It might be worth revisiting #326, anyway. IIRC it mostly worked (and didn't sound different OTA from what I remember) but a few ctests failed due to a few of the bytes being different. However, that PDF is also ~150 KB, which I'm not sure is a realistic size for HF.

As noted in #326, the proposed optimisations broke the compression algorithm, and provided just 0.08% CPU improvement on x86.

@tmiw
Copy link
Collaborator

tmiw commented Dec 31, 2022

Yep it's the Rx side and specifically acquisition that we had in mind. So its CPU load with no modem signal (e.g. just noise for ch). Possibly just some vectorisation on the inner loop DSP.

#374 has initial work on this.

As noted in #326, the proposed optimisations broke the compression algorithm, and provided just 0.08% CPU improvement on x86.

Yeah, it'd likely not use that implementation if we were to try optimizing BPF again. But it sounds like that's not too high of a priority anyway, at least for now.

@drowe67
Copy link
Owner Author

drowe67 commented Apr 13, 2023

@DJ2LS here are a few candidates for datac4 against our design target, for 100 packet tests in Octave. I'm trying out:

  1. A rate 1/3 code (768,256) which has only 256 data bits in the codeword, so 240 bits after we use 16 for the CRC.
  2. A rate 1/2 (1152,576) code, 560 bits after the CRC.
Name Throughput bits/s Payload bits Duration Channel SNR PER
datac3 320 1008 3.2 MPP 0 0.2
FreeDATA-003 target 80 448 5.6 MPP -5 0.1
ae9c96 68 240 3.7 MPP -4 0.22
ae9c96 68 240 3.7 MPP -6 0.32
ae9c96 68 240 3.7 AWGN -8 0.05
f82b868 104 560 5.5 MPP -4 0.41
  1. ae9c96 works about 4dB lower than datac3. With the MPP channel I'm finding it hard to hit PER=0.1 at -5dB, I think due to the narrow, 3 carrier signal making acquisition and MPP performance harder. However it does seem to get a reasonable number of packet through at quite low SNRs. That might be a useful property for the low SNR "maintain some sort of link" use case.

  2. The longer rate 1/2 (1152,576) code in f82b868 doesn't perform very well, not sure why.

@DJ2LS
Copy link
Contributor

DJ2LS commented Apr 13, 2023

3.7

What if we increasing carriers to 4? I'm not sure, but IIRC this was a good tradeoff in past, when doing some testing in this area, I think.

Regarding to 2.) Maybe thats because of the MPP channel simulation? IIRC, signal disruption occurs cyclic in octave simulation. Means, we would always loose bits at the same position. But thats not the case in real world situation I think. In other words - maybe the longer rate is working better than expected in real world scenarios?

@drowe67
Copy link
Owner Author

drowe67 commented Apr 21, 2023

@DJ2LS drowe67/codec2@c416cd4 is is a work in progress and currently introducing bit errors. I'll fix it over the next week after ⛵

@DJ2LS
Copy link
Contributor

DJ2LS commented Apr 22, 2023

@DJ2LS c416cd4 is is a work in progress and currently introducing bit errors. I'll fix it over the next week after boat

Ah yes, thanks, now the SNR returns a more realistic value.

@drowe67
Copy link
Owner Author

drowe67 commented Apr 29, 2023

Re e7811cd - performed a few iterations around ofdm_acquisition to tune timing_mx_thresh, trying ofdm_ldpc_rx on 100 packets (MPP, -4dB), and adjusting centre freq and bandwidth of complex input filter rxbpf_width_Hz between 400 and 600 Hz.

Pacq and Pacq_false are outputs from ofdm_acquisition, Pacq_false means our timing metric exceeds the threshold, but it wasn't a valid pre or post-amble. This means the state machine would kick in, and we would get a UW fail after a few modem frames.

PER calculated from ofdm_ldpc_rx as PER=1-(Pckts-Perrs)/100.

Example Octave ofdm_ldpc_rx run:

ofdm_ldpc_tx('test_datac13.raw','datac13',1,-4,'mpp','bursts',100);
ofdm_ldpc_rx('test_datac13.raw','datac13','packetsperburst',1);
Mode timing_mx_thresh rxbpf_width_Hz Pacq Pacq_false Octave PER C PER
datac4 0.5 400 0.91 0.02 0.12 0.13
datac13 0.45 400 0.88 0.09 0.11 0.12

The final col is the PER from the C port 7264290, using the same test_datac4.raw file as for the Octave test.

./src/ofdm_demod --mode datac4 --in ../octave/test_datac4.raw --out /dev/null --testframes --ldpc --verbose 2 --packetsperburst 1

drowe67 added 4 commits April 29, 2023 10:30
…s, and filter bandwidth adjustments, PER about 0.1 at -4dB MPP for datac4 & c13
… tuned datac13 and datac4 tx BPF and clippers, about 1dB compression gain for no impact on MPP -4dB PER
@drowe67
Copy link
Owner Author

drowe67 commented Apr 29, 2023

drowe67/codec2@ff5f86b Tuning clipping and Tx BPF in Octave. Not much gain from clipper in these modes as Nc is small, so vanilla PAPR before clipping is already low at 5.5 dB. So just a small amount of clipping added with tx BPF, that adds just a little noise to scatter diagram, and doesn't impact PER at a given SNR. We get a 1dB improvement in PAPR and hence Rx SNR for a given peak power.

Comparison of clipping with Octave simulation for 100 packets.

Mode txclip CPAPR Channel SNR PER
datac4 0 5.78 MPP -4 0.11
datac13 0 5.62 MPP -4 0.12
datac4 1 4.82 MPP -4 0.10
datac13 1 4.68 MPP -4 0.11

@drowe67
Copy link
Owner Author

drowe67 commented May 1, 2023

After C port I realised I was forgetting to add the correction burst offset for PAPR, so lets try again.

Octave for 100 Tx packets:

ofdm_ldpc_tx('test_datac13.raw','datac13',1,100,'awgn','bursts',100,'txclip');
Mode txclip CPAPR Burst Offset CPAPR Corrected
datac4 0 5.62 -0.75 4.87
datac13 0 5.78 -1.64 4.14
datac4 1 4.68 -0.75 3.93
datac13 1 4.82 -1.64 3.20

C for 100 Tx packets:

./src/freedv_data_raw_tx --bursts 100 --testframes 100 DATAC13 /dev/zero - | ./src/ch - /dev/null
Mode txclip CPAPR Burst Offset CPAPR Corrected
datac4 0 6.71 -0.18 6.53
datac13 0 5.88 -0.42 4.46
datac4 1 4.15 -0.18 3.97
datac13 1 4.52 -0.42 4.10

Not sure why the C PAPRs are a bit higher 🤔

@drowe67
Copy link
Owner Author

drowe67 commented May 2, 2023

@DJ2LS, some PER curves. A few thoughts:

  1. datac13 on AWGN is impressive, still working at -10dB.
  2. You can see 20% PER at -7dB MPP, explains your spots.
  3. The two new modes hit 10% PER at -3.5 to -4 dB, but hang on quite well after that
  4. The new modes are about 5dB lower than datac0/datac3 as we hoped for 👍
  5. The throughput curve shows the trade off: quite slow, but enough for a basic link and small files or emails I guess.
  6. datac1 is 10x faster, with about 10dB more SNR 👍

c_tx_comp
c_tx_comp_thruput

@DJ2LS

This comment was marked as outdated.

@drowe67
Copy link
Owner Author

drowe67 commented May 2, 2023

Interesting plots, @drowe67 , any chance adding the datac5 prototype for comparison with datac1?

Unfortunately those plots require the mode to be running in C.

@drowe67 drowe67 merged commit 39528c4 into master May 3, 2023
@DJ2LS
Copy link
Contributor

DJ2LS commented Mar 13, 2024

@drowe67

saving my thoughts here in case we want to continue working on this:

DATAC5 Octave Experiment:


Ns=5; config.Np=52; Tcp = 0.004; Ts = 0.016; Nc = 39; config.data_mode = "streaming";
config.Ntxtbits = 0; config.Nuwbits = 24; config.bad_uw_errors = 12;
config.state_machine = "data";
config.ftwindow_width = 80; config.amp_est_mode = 1; config.EsNodB = 3;
config.amp_scale = 145E3; config.clip_gain1 = 2.7; config.clip_gain2 = 0.8;
config.edge_pilots = 0; config.timing_mx_thresh = 0.10;
config.tx_uw = zeros(1,config.Nuwbits);
config.tx_uw(1:24) = [1 1 0 0  1 0 1 0  1 1 1 1  1 1 1 1  1 1 1 1  1 1 1 1];

This is resulting into:

symperframe: 195 Nbitsperpacket: 16224 Nsamperframe: 800 Ntxtbits: 0 Nuwbits: 24 Nuwframes: 2
uncoded bits/s: 3120.0
ldpc_data_bits_per_frame = 9720
ldpc_coded_bits_per_frame  = 16200
ldpc_parity_bits_per_frame  = 6480
Nbitsperpacket  = 16224
totalbitsperframe = 16224

<snip>

Raw BER..: 0.0811 Tbits: 1622400 Terrs: 131597 SNR3k:  6.62
Coded BER: 0.0069 Tbits: 972000 Terrs:  6675
Coded PER: 0.0700 Pckts:   100 Perrs:     7 Npre: 99 Npost: 1

In a nutshell:

Bandwidth: 2438Hz, 
Coded bitrate: 1872bit/s 
MPP Test:  93/100 @ 8dB

--> This would result in a +3dB operating level at MPP, compared to datac1, but with a +3dB of bitrate

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.

4 participants