NXDN: Fix NXDN_LICH_OFFBITS and LICH_ERR_THRESHOLD to work as expected post NXDN Viterbi overhaul; Revert back to 1 bit error on lich "dividing";

NXDN: Skip Dibits prior to exit on bad sync in nxdn_frame;

NXDN: Reimplement the CAC fail demodulator and dibit buffer soft reset;
This commit is contained in:
lwvmobile
2026-02-01 20:19:33 -05:00
parent 3ee5acef0a
commit 034855069a
3 changed files with 53 additions and 9 deletions

View File

@@ -591,6 +591,7 @@ void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits)
}
static int cac_fail = 0;
void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits)
{
@@ -646,6 +647,10 @@ void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits)
fprintf (stderr, "%s", KNRM);
}
//check for accumulative cac failures and reset if multiple errors pile up
if (crc != 0) cac_fail++;
else cac_fail = 0;
if (crc == 0) NXDN_Elements_Content_decode(opts, state, 1, cac_message_buffer);
if (opts->payload == 1)
@@ -660,6 +665,45 @@ void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits)
if (crc != 0) fprintf (stderr, " CRC ERR ");
}
//reset some parameters if CAC continues to fail
if (cac_fail > 5)
{
//simple reset
state->synctype = -1; //was 0, which is p25p1
state->lastsynctype = -1;
state->carrier = 0;
state->last_cc_sync_time = time(NULL)+2; //probably not necesary
cac_fail = 0; //reset
//more advanced modulator reset
state->center = 0;
state->jitter = -1;
state->synctype = -1;
state->min = -15000;
state->max = 15000;
state->lmid = 0;
state->umid = 0;
state->minref = -12000;
state->maxref = 12000;
state->lastsample = 0;
for (int i = 0; i < 128; i++) state->sbuf[i] = 0;
state->sidx = 0;
for (int i = 0; i < 1024; i++) state->maxbuf[i] = 15000;
for (int i = 0; i < 1024; i++) state->minbuf[i] = -15000;
state->midx = 0;
state->symbolcnt = 0;
//reset the dibit buffer
state->dibit_buf_p = state->dibit_buf + 200;
memset (state->dibit_buf, 0, sizeof (int) * 200);
state->offset = 0;
//debug notification
// fprintf (stderr, " RESET CARRIER; ");
}
}
void idas_scch(dsd_opts * opts, dsd_state * state, uint8_t * bits, uint8_t direction)

View File

@@ -13,7 +13,7 @@
#include "dsd.h"
#include "nxdn_const.h"
#define LICH_ERR_THRESHOLD 2 //Threshold for lich dibit "dividing" errors
#define LICH_ERR_THRESHOLD 7 //Threshold for lich dibit "dividing" errors (8 is perfect, 7 is 1 bit error)
// #define NXDN_DEBUG_LICH //print LICH debug info on err on payload == 1
#define NXDN_LICH_OFFBITS //use the offbits to help determine sync status (disable if bad signal / bad sample)
@@ -298,17 +298,17 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
break;
} // end of switch(lich)
// //collect remaining dibits at this point (before bad frame skip)
// for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174
// dbuf[i+8] = getDibit(opts, state);
//collect remaining dibits at this point (before bad frame skip)
for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174
dbuf[i+8] = getDibit(opts, state);
//go to end if bad returns from earlier
if (state->lastsynctype == -1)
goto END;
//collect remaining dibits at this point (after bad frame skip)
for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174
dbuf[i+8] = getDibit(opts, state);
// //collect remaining dibits at this point (after bad frame skip)
// for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174
// dbuf[i+8] = getDibit(opts, state);
//enable these after good lich parity and known lich value
state->carrier = 1;

View File

@@ -19,7 +19,7 @@ static uint32_t prevMetrics[NUM_STATES];
static uint32_t currMetrics[NUM_STATES];
static uint32_t prevMetricsData[NUM_STATES];
static uint32_t currMetricsData[NUM_STATES];
static uint16_t viterbi_history[600];
static uint16_t viterbi_history[600*2];
/**
* @brief Decode unpunctured convolutionally encoded data.
@@ -66,7 +66,7 @@ uint32_t viterbi_decode(uint8_t* out, const uint16_t* in, const uint16_t len)
uint32_t viterbi_decode_punctured(uint8_t* out, const uint16_t* in, const uint8_t* punct, const uint16_t in_len, const uint16_t p_len)
{
uint16_t umsg[400*2]; //unpunctured message
uint16_t umsg[600*2]; //unpunctured message
uint16_t p=0; //puncturer matrix entry
uint16_t u=0; //bits count - unpunctured message
uint16_t i=0; //bits read from the input message