Simple minded rate 3/4 FEC decoding.

This commit is contained in:
Jonathan Naylor
2016-07-14 18:58:03 +01:00
parent 767c30ebf5
commit 9e83d23c48
3 changed files with 58 additions and 22 deletions

View File

@@ -365,11 +365,11 @@ void CDMRSlot::writeModem(unsigned char *data)
bptc.decode(data + 2U, payload);
bptc.encode(payload, data + 2U);
} else if (dataType == DT_RATE_34_DATA) {
LogDebug("DMR Slot %u, received RF rate 3/4 data", m_slotNo);
CDMRTrellis trellis;
unsigned char payload[18U];
trellis.decode(data + 2U, payload);
// trellis.encode(payload, data + 2U);
bool ret = trellis.decode(data + 2U, payload);
if (ret)
trellis.encode(payload, data + 2U);
}
// Regenerate the Slot Type
@@ -1164,11 +1164,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
bptc.decode(data + 2U, payload);
bptc.encode(payload, data + 2U);
} else if (dataType == DT_RATE_34_DATA) {
LogDebug("DMR Slot %u, received network rate 3/4 data", m_slotNo);
CDMRTrellis trellis;
unsigned char payload[18U];
trellis.decode(data + 2U, payload);
// trellis.encode(payload, data + 2U);
bool ret = trellis.decode(data + 2U, payload);
if (ret)
trellis.encode(payload, data + 2U);
}
// Regenerate the Slot Type

View File

@@ -59,29 +59,38 @@ bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload)
dibitsToPoints(dibits, points);
unsigned char tribits[49U];
unsigned char state = 0U;
for (unsigned int i = 0U; i < 49U; i++) {
tribits[i] = 9U;
// Check the original code
unsigned int failPos = checkCode(points, tribits);
if (failPos == 999U) {
tribitsToBits(tribits, payload);
return true;
}
for (unsigned int j = 0U; j < 8U; j++) {
if (points[i] == ENCODE_TABLE[state * 8U + j]) {
tribits[i] = j;
break;
for (unsigned j = 0U; j < 20U; j++) {
unsigned int bestPos = 0U;
unsigned int bestVal = 0U;
for (unsigned int i = 0U; i < 16U; i++) {
points[failPos] = i;
unsigned int pos = checkCode(points, tribits);
if (pos == 999U) {
tribitsToBits(tribits, payload);
return true;
}
if (pos > bestPos) {
bestPos = pos;
bestVal = i;
}
}
if (tribits[i] == 9U) {
LogDebug("Decoding failure at position %u", i);
return false;
}
state = tribits[i];
points[failPos] = bestVal;
failPos = bestPos;
}
tribitsToBits(tribits, payload);
return true;
return false;
}
void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data)
@@ -320,3 +329,29 @@ void CDMRTrellis::tribitsToBits(const unsigned char* tribits, unsigned char* pay
WRITE_BIT(payload, n, b3);
}
}
unsigned int CDMRTrellis::checkCode(const unsigned char* points, unsigned char* tribits) const
{
unsigned char state = 0U;
for (unsigned int i = 0U; i < 49U; i++) {
tribits[i] = 9U;
for (unsigned int j = 0U; j < 8U; j++) {
if (points[i] == ENCODE_TABLE[state * 8U + j]) {
tribits[i] = j;
break;
}
}
if (tribits[i] == 9U)
return i;
state = tribits[i];
}
if (tribits[48U] != 0U)
return 48U;
return 999U;
}

View File

@@ -29,6 +29,7 @@ private:
void pointsToDibits(const unsigned char* points, signed char* dibits) const;
void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const;
void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const;
unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const;
};
#endif