Improve the FEC reconstruction a little.

This commit is contained in:
Jonathan Naylor 2016-07-19 17:24:11 +01:00
parent c63ce4897e
commit 578085134c
2 changed files with 41 additions and 23 deletions

View File

@ -58,39 +58,27 @@ bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload)
unsigned char points[49U]; unsigned char points[49U];
dibitsToPoints(dibits, points); dibitsToPoints(dibits, points);
unsigned char tribits[49U];
// Check the original code // Check the original code
unsigned char tribits[49U];
unsigned int failPos = checkCode(points, tribits); unsigned int failPos = checkCode(points, tribits);
if (failPos == 999U) { if (failPos == 999U) {
tribitsToBits(tribits, payload); tribitsToBits(tribits, payload);
return true; return true;
} }
for (unsigned j = 0U; j < 20U; j++) { unsigned char savePoints[49U];
unsigned int bestPos = 0U; for (unsigned int i = 0U; i < 49U; i++)
unsigned int bestVal = 0U; savePoints[i] = points[i];
for (unsigned int i = 0U; i < 16U; i++) { bool ret = fixCode(points, failPos, payload);
points[failPos] = i; if (ret)
return true;
unsigned int pos = checkCode(points, tribits); if (failPos == 0U)
if (pos == 999U) { return false;
tribitsToBits(tribits, payload);
return true;
}
if (pos > bestPos) { // Backtrack one place for a last go
bestPos = pos; return fixCode(savePoints, failPos - 1U, payload);
bestVal = i;
}
}
points[failPos] = bestVal;
failPos = bestPos;
}
return false;
} }
void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data) void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data)
@ -330,6 +318,35 @@ void CDMRTrellis::tribitsToBits(const unsigned char* tribits, unsigned char* pay
} }
} }
bool CDMRTrellis::fixCode(unsigned char* points, unsigned int failPos, unsigned char* payload) const
{
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 char tribits[49U];
unsigned int pos = checkCode(points, tribits);
if (pos == 999U) {
tribitsToBits(tribits, payload);
return true;
}
if (pos > bestPos) {
bestPos = pos;
bestVal = i;
}
}
points[failPos] = bestVal;
failPos = bestPos;
}
return false;
}
unsigned int CDMRTrellis::checkCode(const unsigned char* points, unsigned char* tribits) const unsigned int CDMRTrellis::checkCode(const unsigned char* points, unsigned char* tribits) const
{ {
unsigned char state = 0U; unsigned char state = 0U;

View File

@ -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;
bool fixCode(unsigned char* points, unsigned int failPos, unsigned char* payload) const;
unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const; unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const;
}; };