mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 08:47:24 -05:00
EDACS: implement voting algorithm for FR BCH checks
This commit is contained in:
@@ -69,6 +69,27 @@ char* get_lcn_status_string(int lcn)
|
||||
return "";
|
||||
}
|
||||
|
||||
//Bitwise vote-compare the three copies of a message received. Note that FR_2 is transmitted inverted.
|
||||
unsigned long long int edacs_vote_fr(unsigned long long int fr_1, unsigned long long int fr_2, unsigned long long int fr_3)
|
||||
{
|
||||
fr_2 = (~fr_2) & 0xFFFFFFFFFF;
|
||||
|
||||
unsigned long long int msg_result = 0;
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
int bit_1 = (fr_1 >> i) & 1;
|
||||
int bit_2 = (fr_2 >> i) & 1;
|
||||
int bit_3 = (fr_3 >> i) & 1;
|
||||
|
||||
//Vote: the value of the bit that we see the most is what we assume is correct
|
||||
if (bit_1 + bit_2 + bit_3 > 1) {
|
||||
msg_result |= (1ll << i);
|
||||
}
|
||||
}
|
||||
|
||||
return msg_result & 0xFFFFFFFFFF;
|
||||
}
|
||||
|
||||
void openWavOutFile48k (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
UNUSED(state);
|
||||
@@ -509,6 +530,9 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
||||
|
||||
}
|
||||
|
||||
//Old logic - take copy 1 of the first and second messages, then verify BCH on them.
|
||||
//
|
||||
//TODO 2024-04-10: Keep this logic around for a bit to compare against new voting implementation.
|
||||
fr_1 = fr_1 & 0xFFFFFFFFFF;
|
||||
fr_4 = fr_4 & 0xFFFFFFFFFF;
|
||||
|
||||
@@ -522,10 +546,34 @@ void edacs(dsd_opts * opts, dsd_state * state)
|
||||
fr_1t = fr_1t & 0xFFFFFFFFFF;
|
||||
fr_4t = fr_4t & 0xFFFFFFFFFF;
|
||||
|
||||
if (fr_1 != fr_1t || fr_4 != fr_4t)
|
||||
int old_bch_pass = (fr_1 == fr_1t) && (fr_4 == fr_4t);
|
||||
|
||||
//New logic - take our 3 copies of the first and second message and vote them to extract the "error-corrected" first
|
||||
//and second message, then verify BCH on that.
|
||||
unsigned long long int msg_1_ec = edacs_vote_fr(fr_1, fr_2, fr_3);
|
||||
unsigned long long int msg_2_ec = edacs_vote_fr(fr_4, fr_5, fr_6);
|
||||
|
||||
unsigned long long int msg_1_ec_m = msg_1_ec >> 12;
|
||||
unsigned long long int msg_2_ec_m = msg_2_ec >> 12;
|
||||
|
||||
//take our message and create a new crc for it, if it matches the old crc, then we have a good frame
|
||||
unsigned long long int msg_1_ec_t = edacs_bch(msg_1_ec_m) & 0xFFFFFFFFFF;
|
||||
unsigned long long int msg_2_ec_t = edacs_bch(msg_2_ec_m) & 0xFFFFFFFFFF;
|
||||
|
||||
int bch_pass = (msg_1_ec == msg_1_ec_t) && (msg_2_ec == msg_2_ec_t);
|
||||
|
||||
if (!bch_pass && !old_bch_pass)
|
||||
{
|
||||
fprintf (stderr, " BCH FAIL ");
|
||||
}
|
||||
else if (bch_pass && !old_bch_pass)
|
||||
{
|
||||
fprintf (stderr, " BCH FAIL (old logic only) ");
|
||||
}
|
||||
else if (!bch_pass && old_bch_pass)
|
||||
{
|
||||
fprintf (stderr, " BCH FAIL (new logic only)");
|
||||
}
|
||||
else //BCH Pass, continue from here.
|
||||
{
|
||||
|
||||
|
||||
Reference in New Issue
Block a user