mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-20 22:45:44 +08:00
Simple minded rate 3/4 FEC decoding.
This commit is contained in:
12
DMRSlot.cpp
12
DMRSlot.cpp
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user