mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 06:55:52 +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.decode(data + 2U, payload);
|
||||||
bptc.encode(payload, data + 2U);
|
bptc.encode(payload, data + 2U);
|
||||||
} else if (dataType == DT_RATE_34_DATA) {
|
} else if (dataType == DT_RATE_34_DATA) {
|
||||||
LogDebug("DMR Slot %u, received RF rate 3/4 data", m_slotNo);
|
|
||||||
CDMRTrellis trellis;
|
CDMRTrellis trellis;
|
||||||
unsigned char payload[18U];
|
unsigned char payload[18U];
|
||||||
trellis.decode(data + 2U, payload);
|
bool ret = trellis.decode(data + 2U, payload);
|
||||||
// trellis.encode(payload, data + 2U);
|
if (ret)
|
||||||
|
trellis.encode(payload, data + 2U);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerate the Slot Type
|
// Regenerate the Slot Type
|
||||||
@@ -1164,11 +1164,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
bptc.decode(data + 2U, payload);
|
bptc.decode(data + 2U, payload);
|
||||||
bptc.encode(payload, data + 2U);
|
bptc.encode(payload, data + 2U);
|
||||||
} else if (dataType == DT_RATE_34_DATA) {
|
} else if (dataType == DT_RATE_34_DATA) {
|
||||||
LogDebug("DMR Slot %u, received network rate 3/4 data", m_slotNo);
|
|
||||||
CDMRTrellis trellis;
|
CDMRTrellis trellis;
|
||||||
unsigned char payload[18U];
|
unsigned char payload[18U];
|
||||||
trellis.decode(data + 2U, payload);
|
bool ret = trellis.decode(data + 2U, payload);
|
||||||
// trellis.encode(payload, data + 2U);
|
if (ret)
|
||||||
|
trellis.encode(payload, data + 2U);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerate the Slot Type
|
// Regenerate the Slot Type
|
||||||
|
|||||||
@@ -59,29 +59,38 @@ bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload)
|
|||||||
dibitsToPoints(dibits, points);
|
dibitsToPoints(dibits, points);
|
||||||
|
|
||||||
unsigned char tribits[49U];
|
unsigned char tribits[49U];
|
||||||
unsigned char state = 0U;
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 49U; i++) {
|
// Check the original code
|
||||||
tribits[i] = 9U;
|
unsigned int failPos = checkCode(points, tribits);
|
||||||
|
if (failPos == 999U) {
|
||||||
|
tribitsToBits(tribits, payload);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int j = 0U; j < 8U; j++) {
|
for (unsigned j = 0U; j < 20U; j++) {
|
||||||
if (points[i] == ENCODE_TABLE[state * 8U + j]) {
|
unsigned int bestPos = 0U;
|
||||||
tribits[i] = j;
|
unsigned int bestVal = 0U;
|
||||||
break;
|
|
||||||
|
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) {
|
points[failPos] = bestVal;
|
||||||
LogDebug("Decoding failure at position %u", i);
|
failPos = bestPos;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = tribits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tribitsToBits(tribits, payload);
|
return false;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data)
|
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);
|
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 pointsToDibits(const unsigned char* points, signed char* dibits) const;
|
||||||
void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const;
|
void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const;
|
||||||
void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const;
|
void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const;
|
||||||
|
unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user