diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 901a8cb..4b39441 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -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. {