-
Notifications
You must be signed in to change notification settings - Fork 5
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
End of Over Data #35
base: main
Are you sure you want to change the base?
End of Over Data #35
Conversation
…ew bi errors at a reasonable SNR
…his is a weakness in the test designs
@tmiw re
|
@tmiw - take a look at |
I looked at the code again and it looks like it can do hard decision if it absolutely needed to. The relevant part from codec2: if (obj->bit_index == obj->sym_index * 2) {
// Use soft decision for the LDPC decoder.
int Npayloadsymsperpacket = LDPC_TOTAL_SIZE_BITS / 2;
// Deinterleave symbols
gp_deinterleave_comp(
(COMP*)deinterleavedSyms,
(COMP*)&obj->inbound_pending_syms[RELIABLE_TEXT_UW_LENGTH_BITS / 2],
Npayloadsymsperpacket);
gp_deinterleave_float(
deinterleavedAmps,
&obj->inbound_pending_amps[RELIABLE_TEXT_UW_LENGTH_BITS / 2],
Npayloadsymsperpacket);
float EsNo = 3.0; // note: constant from freedv_700.c
symbols_to_llrs(llr, (COMP*)deinterleavedSyms, deinterleavedAmps, EsNo,
obj->fdv->ofdm->mean_amp, Npayloadsymsperpacket);
} else {
// Deinterlace the received bits.
gp_deinterleave_bits(deinterleavedBits, src, LDPC_TOTAL_SIZE_BITS / 2);
// We don't have symbol data (likely due to incorrect mode), so we fall back
// to hard decision.
for (int bitIndex = 0; bitIndex < LDPC_TOTAL_SIZE_BITS; bitIndex++) {
// fprintf(stderr, "rx bit %d: %d\n", bitIndex,
// deinterleavedBits[bitIndex]);
// Map to value expected by sd_to_llr()
incomingData[bitIndex] = 1.0 - 2.0 * deinterleavedBits[bitIndex];
}
sd_to_llr(llr, incomingData, LDPC_TOTAL_SIZE_BITS);
}
run_ldpc_decoder(&obj->ldpc, output, llr, &parityCheckCount); Not sure if the interleaving is needed, either. Regardless, if it's easy to provide the stuff needed for soft decision, that's fine.
Looking now. |
@@ -109,7 +110,9 @@ RADE_EXPORT int rade_tx_eoo(struct rade *r, RADE_COMP tx_eoo_out[]); | |||
RADE_EXPORT int rade_nin(struct rade *r); | |||
|
|||
// returns non-zero if features_out[] contains valid output. The number | |||
// returned is the number of samples written to features_out[] | |||
// returned is the number of samples written to features_out[]. If the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be a bit clearer to have a separate eoo_bits_out
argument and an indicator that this has been populated, i.e.
RADE_EXPORT int rade_rx(struct rade *r, float features_out[], bool* has_eoo_out, float eoo_out[], RADE_COMP rx_in[]);
i.e.
bool has_eoo_out = false;
int ret = rade_rx(r, features_out, &has_eoo_out, eoo_out, rx_in);
if (has_eoo_out) {
// do something with the EOO bits
}
Also, I don't see a way to populate the EOO bits for TX yet?
We should use soft decision if supported.
What you are suggesting is significantly more work. In the spirit of this feature - is it really necessary or will my proposal do the job? This will all be tossed away in 6 months and replaced with a new system (and new API for txt that returns a constant low bit rate like existing FreeDV modes). Oops I forgot Tx, will attend to that. |
Thinking further 🤔 - we should be able to implement the API you have suggested, e.g.:
With some re-arrangement on the C side only, i.e. avoiding moving all of that stuff over the C-Python interface (my main concern). I'll get something working with my original proposal then see if we can refactor. |
Hi @tmiw - I think this is ready for you to try hooking up to the reliable text system. Pls see the PR description ☝️ for demo instructions and limitations. |
|
||
// note vocoder is not encapsulated in API in this version | ||
// returns number of RADE_COMP samples written to tx_out[] | ||
RADE_EXPORT int rade_tx(struct rade *r, RADE_COMP tx_out[], float features_in[]); | ||
|
||
// Set the rade_n_eoo_bits() bits to be sent in the EOO frame, which are | ||
// in +/- 1 float form (note NOT 1 or 0) | ||
RADE_EXPORT void rade_tx_set_eoo_bits(struct rade *r, float eoo_bits[]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the code from codec2 just passes the bits directly for TX instead of using floats. Is that viable to do here too? If not, is there already some sort of way to convert to the form this function needs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you pls describe the format of the bits generated by reliable text?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically, the existing codec2 reliable_text system ties into the varicode functionality. When you set a callsign (https://github.com/drowe67/codec2/blob/main/src/reliable_text.c#L384), it does the following:
- Converts the ASCII callsign into a special six-bit character set. This effectively generates a 48-bit string of zeros and ones.
- Calculates the CRC8 of the above 48-bit string and appends it to the end. This results in 56 bits of data.
- Generates parity bits with the
HRA_56_56
LDPC code and appends to the end of (2). (I have mentions of LDPC(112,56) in the comments but that might be wrong.) We now have 112 bits of data. - Interleaves the parity and data bits together.
- Saves this result somewhere in memory.
When codec2 calls the TX callback that reliable_text injects (https://github.com/drowe67/codec2/blob/main/src/reliable_text.c#L340), the latter returns the next byte of data from (5), i.e.
- Call 1:
return txString[0]
- Call 2:
return txString[1]
- ...
- Call 14:
return txString[13]
- Call 15:
return txString[0]
- ...
This is then injected into the data transmitted over the air.
Anyway, I hope this helps. Let me know if you need further clarification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK so I think this is the array of bits to be sent to the modem:
char tx_text[LDPC_TOTAL_SIZE_BITS + RELIABLE_TEXT_UW_LENGTH_BITS];
So the format is one bit per char. We'll need some glue code to connect reliable text to the EOO modem. So on the tx side we want a binary 1 -> +1, and binary 0 -> -1, something like:
eoo_bit[i] = 2.0*tx_text[i] - 1.0;
The LDPC decoder expects the received symbol to be mapped to the QPSK constellation defined by (codec2/src/mp_decode.c
:
static COMP S_matrix[] = {
{1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}};
which is 45 degrees rotated from the EOO text constellation {1,1}, {-1,1}, {-1,-1}, {1,-1} . So on the rx side, something like (ROT45 from codec2/src/ofdm.c
):
complex float symbol = (COMP)eoo_out[2*i];
reliable_text_demod_symbol[i] = symbol * cmplx(ROT45);
Good idea to have a unit tests that runs with no noise, make sure the LDPC decoding happens with 1 iteration, just to make sure we haven't messed up anything. Then add some noise, e.g. 2-3dB AWGN and make sure it hangs on. Not sure where to do the tests .. it's a mash up of several repos 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure where to do the tests .. it's a mash up of several repos
Considering the current API, I wonder if having this in freedv-gui would be best. That way, it'd have access to some of the codec2 functions (e.g. LDPC and interleaving) and we wouldn't need to reimplement versions in this repo. OTOH testing does become a bit harder but maybe doable with the current test framework. If that sounds good, I'll go ahead and do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I agree, it's the only project with everything linked in. And you now have a nice command line test framework for freedv-gui
to support automated tests :+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I created drowe67/freedv-gui#783 but I suspect there's something wrong with either the TX or RX symbol generation; BER is much too high when playing back files generated locally (i.e. no RF). I also disabled interleaving just to be sure that wasn't interfering. I'll have to investigate more when I have time.
@@ -426,7 +457,7 @@ int rade_tx_eoo(struct rade *r, RADE_COMP tx_eoo_out[]) { | |||
return r->Neoo; | |||
} | |||
|
|||
int rade_rx(struct rade *r, float features_out[], RADE_COMP rx_in[]) { | |||
int rade_rx(struct rade *r, float features_out[], int *has_eoo_out, float eoo_out[], RADE_COMP rx_in[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to make sure, eoo_out
is basically structured so that odd indexed items are symbols and even indexed symbols are amplitudes, right? i.e.
eoo_out[0] = real value of symbol
eoo_out[1] = complex value of symbol
eoo_out[2] = amplitude
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the notes above rade_rx()
in rade_api.h
help?
For the LDPC decoder you will need to calculate the symbol amplitudes. As a starting point, I'd suggest making one estimate for the entire vector (e.g. the RMS amplitude across all symbols) and filling all entries of the amplitude[] vector with that value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually didn't see that comment originally, sorry about that. I'll think about it some more.
An approach to get some sort of text support for RADE V1, to support FreeDV and PSK reporter messaging. Up to 180 bits are inserted in to the End of Over frame.
Limitations:
TODO PoC:
TODO completion:
ctest -V -R radae_eoo_data_mpp
Demo Results:
Test on a MPP channel at 6dB SNR, 5 "overs" are sent, and we attempt to get at least one EOO data packet with a raw BER < 5%.