DMR Burst Type FEC Fix;

This commit is contained in:
lwvmobile
2022-10-17 17:16:22 -04:00
parent 0bb9dd760c
commit 4138f92917
6 changed files with 116 additions and 92 deletions

View File

@@ -25,23 +25,17 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
int *dibit_p;
char sync[25];
char syncdata[48];
char cachdata[25] = {0}; //increased from 24 to 25 to see if this fixes ubuntu 32 bug
char cachdata[25] = {0};
char cc[5] = {0};
char ccAscii[5] = {0};
char bursttype[5];
unsigned int burst;
char info[196];
// char SlotType[20]; //was char, but I don't think FEC brings back good values when usign that
unsigned char SlotType[20]; //was char, but I don't think FEC brings back good values when usign that
unsigned char SlotType[20];
unsigned int SlotTypeOk;
int cachInterleave[24] = {0, 7, 8, 9, 1, 10, 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23};
/* Remove warning compiler */
//UNUSED_VARIABLE(cachdata[0]);
//UNUSED_VARIABLE(cc[0]);
//UNUSED_VARIABLE(ccAscii[0]);
#ifdef DMR_DUMP
char syncbits[49];
char cachbits[25];
@@ -51,16 +45,8 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
ccAscii[4] = 0;
bursttype[4] = 0;
//dibit_p = state->dibit_buf_p - 90;
//using the estimate_symbol method for the dmr_payload_p buffer causes sync
//issues with P25, so only do it when frame_p25p1 == 0, or -fr option
//temp fix to only use dmr_payload_p buffer when no inversion expected, otherwise use dibit_buf
// if (opts->frame_p25p1 == 0 && opts->inverted_dmr == 0) //opts->frame_p25p1 == 0 && opts->inverted_dmr == 0
// {
// dibit_p = state->dmr_payload_p - 90;
// }
dibit_p = state->dmr_payload_p - 90;
// CACH, why aren't we running any FEC on this?
// CACH
for (i = 0; i < 12; i++)
{
dibit = *dibit_p;
@@ -73,39 +59,14 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
{
dibit = (int)state->dmr_stereo_payload[i];
}
//fprintf(stderr, "%X", dibit);
//cachdata[i] = dibit;
cachdata[cachInterleave[(i*2)]] = (1 & (dibit >> 1)); // bit 1
cachdata[cachInterleave[(i*2)+1]] = (1 & dibit); // bit 0
// cachdata[(i*2)] = (1 & (dibit >> 1)); // bit 1
// cachdata[(i*2)+1] = (1 & dibit); // bit 0
if (i == 2)
{
/* Change the current slot only if we are in relayed mode (not in direct mode) */
// if(state->directmode == 0) state->currentslot = (1 & (dibit >> 1)); //move this until after cach fec performed
//
// if (state->currentslot == 0 && state->dmr_ms_mode == 0)
// {
// state->slot1light[0] = '[';
// state->slot1light[6] = ']';
// state->slot2light[0] = ' ';
// state->slot2light[6] = ' ';
// }
// //else
// if (state->currentslot == 1 && state->dmr_ms_mode == 0)
// {
// state->slot2light[0] = '[';
// state->slot2light[6] = ']';
// state->slot1light[0] = ' ';
// state->slot1light[6] = ' ';
// }
}
}
//cachdata[12] = 0;
cachdata[25] = 0; //setting to see if this fixes ubuntu 32 bit bug
cachdata[25] = 0;
//decode and correct cach and compare
int cach_okay = 69;
if ( Hamming_7_4_decode (cachdata) ) //is now de-interleaved appropriately
@@ -221,10 +182,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
{
dibit = (int)state->dmr_stereo_payload[63]; //(int)
}
// burst = (unsigned int)((1 & (dibit >> 1)) << 3);
// burst |= (unsigned int)((1 & (dibit >> 0)) << 2);
// bursttype[0] = (1 & (dibit >> 1)) + 48; // bit 1
// bursttype[1] = (1 & dibit) + 48; // bit 0
SlotType[4] = (1 & (dibit >> 1)); // bit 1
SlotType[5] = (1 & dibit); // bit 0
@@ -238,10 +196,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
{
dibit = (int)state->dmr_stereo_payload[64]; //(int)
}
// burst |= (unsigned int)((1 & (dibit >> 1)) << 1);
// burst |= (unsigned int)((1 & (dibit >> 0)) << 0);
// bursttype[2] = (1 & (dibit >> 1)) + 48; // bit 1
// bursttype[3] = (1 & dibit) + 48; // bit 0
SlotType[6] = (1 & (dibit >> 1)); // bit 1
SlotType[7] = (1 & dibit); // bit 0
@@ -259,7 +214,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
SlotType[8] = (1 & (dibit >> 1)); // bit 1
SlotType[9] = (1 & dibit); // bit 0
// signaling data or sync
// signalling data or sync
for (i = 0; i < 24; i++)
{
dibit = *dibit_p;
@@ -270,13 +225,15 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
}
if (state->dmr_stereo == 1)
{
dibit = (int)state->dmr_stereo_payload[i+66]; //double check these i+ values make sure we are on the right ones
dibit = (int)state->dmr_stereo_payload[i+66];
}
syncdata[2*i] = (1 & (dibit >> 1)); // bit 1
syncdata[(2*i)+1] = (1 & dibit); // bit 0
sync[i] = (dibit | 1) + 48;
}
sync[24] = 0; //why?
sync[24] = 0;
#ifdef DMR_DUMP
k = 0;
@@ -340,8 +297,8 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
}
/* Check and correct the SlotType (apply Golay(20,8) FEC check) */
//pretty sure this isn't working correcty, does not apply corrected bits, due to cast type mismatching
// if(Golay_20_8_decode((unsigned char *)SlotType)) SlotTypeOk = 1;
// golay (20,8) hamming-weight of 6 reliably corrects at most 2 bit-errors
if( Golay_20_8_decode(SlotType) )
{
SlotTypeOk = 1;
@@ -354,10 +311,8 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
}
/* Slot Type parity checked => Fill the color code */
//state->color_code = (unsigned int)((cc[0] << 3) + (cc[1] << 2) + (cc[2] << 1) + cc[3]);
state->color_code = (SlotType[0] << 3) + (SlotType[1] << 2) +(SlotType[2] << 1) + (SlotType[3] << 0);
state->color_code_ok = SlotTypeOk;
//fprintf(stderr, "| Color Code=%02d ", (int)state->color_code);
/* Reconstitute the burst type */
//consider assigning this only when slottypeok or similar check passes, eliminate bad burst types from decoding randomly
@@ -594,7 +549,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
if (SlotTypeOk == 0 || cach_okay == 0)
{
fprintf (stderr, "%s", KRED);
fprintf (stderr, " **CACH or Burst Type FEC ERR - SKIPPING** ");
fprintf (stderr, "| **CACH or Burst Type FEC ERR ** ");
fprintf (stderr, "%s", KNRM);
fprintf (stderr, "\n");
}

View File

@@ -26,6 +26,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
int msMode;
char cc[4];
unsigned char EmbeddedSignalling[16];
unsigned char EmbeddedSignallingInverse[16];
int EmbeddedSignallingOk;
unsigned int internalcolorcode;
int internalslot;
@@ -71,8 +72,8 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
short int m = 0;
state->dmrburstL = 16; //Use 16 for Voice?
// No CACH in MS/DM Mode?
state->dmrburstL = 16; //Use 16 for Voice
for(i = 0; i < 12; i++)
{
dibit = getDibit(opts, state);
@@ -82,11 +83,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
}
cachdata[i] = dibit;
state->dmr_stereo_payload[i] = dibit;
if(i == 2)
{
//state->currentslot = (1 & (dibit >> 1));
//internalslot = (1 & (dibit >> 1));
}
}
//Setup for first AMBE Frame
@@ -193,11 +190,28 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
sync[24] = 0;
EmbeddedSignallingOk = -1;
// for (i = 0; i < 16; i++)
// {
// EmbeddedSignallingInverse[i] = EmbeddedSignalling[i] ^ 1;
// }
if(QR_16_7_6_decode(EmbeddedSignalling))
{
EmbeddedSignallingOk = 1;
}
//test for inverted signal - this should move to data, and have a slottype check here perhaps?
// else if (QR_16_7_6_decode(EmbeddedSignallingInverse))
// {
// if (opts->inverted_dmr == 0)
// {
// opts->inverted_dmr = 1;
// }
// else opts->inverted_dmr = 0;
// goto END;
// }
internalcolorcode = 69; //set so we know if this value is being set properly
if(EmbeddedSignallingOk == 1)
{
@@ -543,14 +557,13 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
}
state->dmrburstL = 16; //Use 16 for Voice?
dibit_p = state->dmr_payload_p - 90;
//payload buffer tests
//CACH + First Half Payload + Sync = 12 + 54 + 24
for (i = 0; i < 90; i++) //90
{
state->dmr_stereo_payload[i] = *dibit_p;
dibit_p++;
}
//end payload buffer test
for(i = 0; i < 12; i++)
{
@@ -614,11 +627,12 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
z++;
}
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
for(i = 0; i < 18; i++)
{
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
@@ -770,7 +784,7 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
unsigned char MSSlot[20] = {0}; //10 dibits = 20 bits
unsigned char MSBurst[5] = {0};
int cachInterleave[24] = {0, 7, 8, 9, 1, 10, 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23};
//int cachInterleave[24] = {0,}
//add time to mirror sync
time_t now;
char * getTime(void) //get pretty hh:mm:ss timestamp
@@ -789,8 +803,8 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
}
b = 0;
c = 0;
//CACH + First Half Payload + Sync = 12 + 54 + 24
//dibit_p = state->dibit_buf_p - 90;
dibit_p = state->dmr_payload_p - 90;
for (i = 0; i < 90; i++) //90
{
@@ -798,7 +812,7 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
dibit_p++;
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i] = dibit;
//load cach
@@ -826,6 +840,10 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
for (i = 0; i < 54; i++)
{
dibit = getDibit(opts, state);
if(opts->inverted_dmr == 1)
{
dibit = (dibit ^ 2);
}
state->dmr_stereo_payload[i+90] = dibit;
//load slot, second half
if (i < 6)
@@ -839,8 +857,8 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
//state->directmode = 0; //flag off for testing
//hide behind payload due to errs in data in MS/DM mode
if (opts->payload == 1 && state->directmode == 0)
//with FEC fix, now we can (hopefully) feel confident in running MS data
if (1 == 1) //opts->payload == 1 && state->directmode == 0
{
fprintf (stderr, "%s ", getTime());
if (opts->inverted_dmr == 0)
@@ -850,6 +868,34 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
else fprintf (stderr,"Sync: -DMR MS/DM MODE ");
}
// decode and correct cach and slot
// golay (20,8) hamming-weight of 6 reliably corrects at most 2 bit-errors
int cach_okay = -1;
if ( Hamming_7_4_decode (MSCach) )
{
cach_okay = 1;
}
if (cach_okay == 1)
{
//fprintf (stderr, "CACH Okay ");
}
else
{
//fprintf (stderr, "CACH ERR ");
goto END;
}
int slot_okay = -1;
if(Golay_20_8_decode(MSSlot))
{
slot_okay = 1;
}
if (slot_okay == 1)
{
//fprintf (stderr, "Slot Okay ");
}
else goto END;
sprintf(state->slot1light, "%s", "");
sprintf(state->slot2light, "%s", "");
@@ -858,23 +904,33 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
state->dmr_stereo = 1;
state->dmr_ms_mode = 1;
//only run if payload is set to 1 due to errors with MS data
if (opts->payload == 1 && state->directmode == 0) //don't run on Direct Mode just yet
//with FEC fix, now we can (hopefully) feel confident in running MS data
if (1 == 1) //opts->payload == 1 && state->directmode == 0
{
processDMRdata (opts, state);
}
END:
if (slot_okay != 1 || cach_okay != 1)
{
fprintf (stderr, "%s", KRED);
fprintf (stderr, "| **CACH or Burst Type FEC ERR ** ");
fprintf (stderr, "%s", KNRM);
fprintf (stderr, "\n");
}
state->dmr_stereo = 0;
state->dmr_ms_mode = 0;
state->directmode = 0; //flag off
//get potential first half payload dibits and store them in the payload for the next repitition, MS voice or data.
skipDibit (opts, state, 144);
//CACH + First Half Payload = 12 + 54
for (i = 0; i < 66; i++) //66
{
dibit = getDibit(opts, state);
state->dmr_stereo_payload[i] = dibit;
state->dmr_stereo_payload[i] = dibit;
}
}

View File

@@ -170,7 +170,7 @@ use_symbol (dsd_opts* opts, dsd_state* state, int symbol)
}
// Increase sidx
if (state->sidx == (opts->ssize - 1))
if (state->sidx >= (opts->ssize - 1))
{
state->sidx = 0;
@@ -315,13 +315,11 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
state->last_dibit = dibit;
// store non-inverted values in dibit_buf
*state->dibit_buf_p = invert_dibit(dibit);
state->dibit_buf_p++;
//dmr buffer
*state->dmr_payload_p = invert_dibit(dibit); //invert, or no?
// *state->dmr_payload_p = dibit; //invert, or no?
*state->dmr_payload_p = invert_dibit(dibit);
state->dmr_payload_p++;
//dmr buffer end
@@ -377,9 +375,15 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
}
state->last_dibit = dibit;
*state->dibit_buf_p = dibit;
state->dibit_buf_p++;
//dmr buffer
//note to self, perceived bug with initial dibit buffer appears to be caused by
//media player, when playing back from audacity, the initial few dmr frames are
//decoded properly, need to investigate the root cause of what audacity is doing
//vs other audio sources...perhaps just the audio level itself?
*state->dmr_payload_p = dibit;
state->dmr_payload_p++;
//dmr buffer end

View File

@@ -955,7 +955,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
}
//return (33);
return (33);
}
else
{
@@ -998,7 +998,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
}
//return (33);
return (33);
}
else
{
@@ -1100,7 +1100,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
//printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation);
}
state->lastsynctype = 13;
//return (33);
return (33);
}
} /* End if(strcmp (synctest, DMR_DIRECT_MODE_TS1_VOICE_SYNC) == 0) */
if(strcmp (synctest, DMR_DIRECT_MODE_TS2_VOICE_SYNC) == 0)
@@ -1143,7 +1143,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
}
//return (33);
return (33);
}
} //End if(strcmp (synctest, DMR_DIRECT_MODE_TS2_VOICE_SYNC) == 0)
} //End if (opts->frame_dmr == 1)

View File

@@ -76,7 +76,6 @@ char * pEnd; //bugfix
void
noCarrier (dsd_opts * opts, dsd_state * state)
{
// state->testcounter = 0;
state->dibit_buf_p = state->dibit_buf + 200;
memset (state->dibit_buf, 0, sizeof (int) * 200);
//dmr buffer
@@ -84,9 +83,9 @@ noCarrier (dsd_opts * opts, dsd_state * state)
memset (state->dmr_payload_buf, 0, sizeof (int) * 200);
//dmr buffer end
if (opts->mbe_out_f != NULL)
{
closeMbeOutFile (opts, state);
}
{
closeMbeOutFile (opts, state);
}
state->jitter = -1;
state->lastsynctype = -1;
state->carrier = 0;

View File

@@ -872,11 +872,14 @@ void Golay_20_8_encode(unsigned char *origBits, unsigned char *encodedBits)
}
}
// golay (20,8) hamming-weight of 6 reliably corrects at most 2 bit-errors
bool Golay_20_8_decode(unsigned char *rxBits)
{
unsigned int syndromeI = 0; // syndrome index
int is = 0;
int i = 0;
//tally corrections made, exceeding 2 will return false
int correction = 0;
for (is = 0; is < 12; is++)
{
@@ -915,6 +918,7 @@ bool Golay_20_8_decode(unsigned char *rxBits)
else
{
rxBits[Golay_20_8_m_corr[syndromeI][i]] ^= 1; // flip bit
correction++;
}
}
@@ -922,6 +926,12 @@ bool Golay_20_8_decode(unsigned char *rxBits)
{
return false;
}
//return false due to exceeding the number of allowed corrected bits
if (correction > 2)
{
return false;
}
}
return true;