Restoring AMBE FEC improvement + fix

This commit is contained in:
Andy CA6JAU 2018-03-07 00:00:46 -03:00
parent 9550b790a7
commit 25bd10fa7d
2 changed files with 127 additions and 90 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010,2014,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2010,2014,2016,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2016 Mathias Weyland, HB9FRV
*
* This program is free software; you can redistribute it and/or modify
@ -21,8 +21,6 @@
#include "Hamming.h"
#include "AMBEFEC.h"
#include "Log.h"
#include <cstdio>
#include <cassert>
@ -446,9 +444,9 @@ const unsigned int PRNG_TABLE[] = {
const unsigned int DMR_A_TABLE[] = { 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, 32U, 36U, 40U, 44U,
48U, 52U, 56U, 60U, 64U, 68U, 1U, 5U, 9U, 13U, 17U, 21U};
const unsigned int DMR_B_TABLE[] = {25U, 29U, 33U, 37U, 41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U,
2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U};
const unsigned int DMR_C_TABLE[] = {50U, 54U, 58U, 62U, 66U, 70U, 3U, 7U, 11U, 15U, 19U, 23U,
27U, 31U, 35U, 39U, 43U, 47U, 51U, 55U, 59U, 63U, 67U, 71U};
2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U};
const unsigned int DMR_C_TABLE[] = {46U, 50U, 54U, 58U, 62U, 66U, 70U, 3U, 7U, 11U, 15U, 19U,
23U, 27U, 31U, 35U, 39U, 43U, 47U, 51U, 55U, 59U, 63U, 67U, 71U};
const unsigned int DSTAR_A_TABLE[] = {0U, 6U, 12U, 18U, 24U, 30U, 36U, 42U, 48U, 54U, 60U, 66U,
1U, 7U, 13U, 19U, 25U, 31U, 37U, 43U, 49U, 55U, 61U, 67U};
@ -479,28 +477,13 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned char* bytes) const
assert(bytes != NULL);
unsigned int a1 = 0U, a2 = 0U, a3 = 0U;
unsigned int b1 = 0U, b2 = 0U, b3 = 0U;
unsigned int c1 = 0U, c2 = 0U, c3 = 0U;
unsigned int MASK = 0x800000U;
for (unsigned int i = 0U; i < 24U; i++) {
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
unsigned int a1Pos = DMR_A_TABLE[i];
unsigned int b1Pos = DMR_B_TABLE[i];
unsigned int c1Pos = DMR_C_TABLE[i];
unsigned int a2Pos = a1Pos + 72U;
if (a2Pos >= 108U)
a2Pos += 48U;
unsigned int b2Pos = b1Pos + 72U;
if (b2Pos >= 108U)
b2Pos += 48U;
unsigned int c2Pos = c1Pos + 72U;
if (c2Pos >= 108U)
c2Pos += 48U;
unsigned int a3Pos = a1Pos + 192U;
unsigned int b3Pos = b1Pos + 192U;
unsigned int c3Pos = c1Pos + 192U;
if (READ_BIT(bytes, a1Pos))
a1 |= MASK;
@ -508,57 +491,83 @@ unsigned int CAMBEFEC::regenerateDMR(unsigned char* bytes) const
a2 |= MASK;
if (READ_BIT(bytes, a3Pos))
a3 |= MASK;
}
unsigned int b1 = 0U, b2 = 0U, b3 = 0U;
MASK = 0x400000U;
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
unsigned int b1Pos = DMR_B_TABLE[i];
unsigned int b2Pos = b1Pos + 72U;
if (b2Pos >= 108U)
b2Pos += 48U;
unsigned int b3Pos = b1Pos + 192U;
if (READ_BIT(bytes, b1Pos))
b1 |= MASK;
if (READ_BIT(bytes, b2Pos))
b2 |= MASK;
if (READ_BIT(bytes, b3Pos))
b3 |= MASK;
}
unsigned int c1 = 0U, c2 = 0U, c3 = 0U;
MASK = 0x1000000U;
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
unsigned int c1Pos = DMR_C_TABLE[i];
unsigned int c2Pos = c1Pos + 72U;
if (c2Pos >= 108U)
c2Pos += 48U;
unsigned int c3Pos = c1Pos + 192U;
if (READ_BIT(bytes, c1Pos))
c1 |= MASK;
if (READ_BIT(bytes, c2Pos))
c2 |= MASK;
if (READ_BIT(bytes, c3Pos))
c3 |= MASK;
MASK >>= 1;
}
unsigned int errors = regenerate(a1, b1, c1, true);
errors += regenerate(a2, b2, c2, true);
errors += regenerate(a3, b3, c3, true);
unsigned int errors = regenerateDMR(a1, b1);
errors += regenerateDMR(a2, b2);
errors += regenerateDMR(a3, b3);
MASK = 0x800000U;
for (unsigned int i = 0U; i < 24U; i++) {
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
unsigned int a1Pos = DMR_A_TABLE[i];
unsigned int b1Pos = DMR_B_TABLE[i];
unsigned int c1Pos = DMR_C_TABLE[i];
unsigned int a2Pos = a1Pos + 72U;
if (a2Pos >= 108U)
a2Pos += 48U;
unsigned int b2Pos = b1Pos + 72U;
if (b2Pos >= 108U)
b2Pos += 48U;
unsigned int c2Pos = c1Pos + 72U;
if (c2Pos >= 108U)
c2Pos += 48U;
unsigned int a3Pos = a1Pos + 192U;
unsigned int b3Pos = b1Pos + 192U;
unsigned int c3Pos = c1Pos + 192U;
WRITE_BIT(bytes, a1Pos, a1 & MASK);
WRITE_BIT(bytes, a2Pos, a2 & MASK);
WRITE_BIT(bytes, a3Pos, a3 & MASK);
}
MASK = 0x400000U;
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
unsigned int b1Pos = DMR_B_TABLE[i];
unsigned int b2Pos = b1Pos + 72U;
if (b2Pos >= 108U)
b2Pos += 48U;
unsigned int b3Pos = b1Pos + 192U;
WRITE_BIT(bytes, b1Pos, b1 & MASK);
WRITE_BIT(bytes, b2Pos, b2 & MASK);
WRITE_BIT(bytes, b3Pos, b3 & MASK);
}
MASK = 0x1000000U;
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
unsigned int c1Pos = DMR_C_TABLE[i];
unsigned int c2Pos = c1Pos + 72U;
if (c2Pos >= 108U)
c2Pos += 48U;
unsigned int c3Pos = c1Pos + 192U;
WRITE_BIT(bytes, c1Pos, c1 & MASK);
WRITE_BIT(bytes, c2Pos, c2 & MASK);
WRITE_BIT(bytes, c3Pos, c3 & MASK);
MASK >>= 1;
}
return errors;
@ -583,7 +592,7 @@ unsigned int CAMBEFEC::regenerateDStar(unsigned char* bytes) const
MASK >>= 1;
}
unsigned int errors = regenerate(a, b, c, false);
unsigned int errors = regenerateDStar(a, b);
MASK = 0x800000U;
for (unsigned int i = 0U; i < 24U; i++) {
@ -601,38 +610,47 @@ unsigned int CAMBEFEC::regenerateYSFDN(unsigned char* bytes) const
assert(bytes != NULL);
unsigned int a = 0U;
unsigned int b = 0U;
unsigned int c = 0U;
unsigned int MASK = 0x800000U;
for (unsigned int i = 0U; i < 24U; i++) {
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
unsigned int aPos = DMR_A_TABLE[i];
unsigned int bPos = DMR_B_TABLE[i];
unsigned int cPos = DMR_C_TABLE[i];
if (READ_BIT(bytes, aPos))
a |= MASK;
if (READ_BIT(bytes, bPos))
b |= MASK;
if (READ_BIT(bytes, cPos))
c |= MASK;
MASK >>= 1;
}
unsigned int errors = regenerate(a, b, c, true);
unsigned int b = 0U;
MASK = 0x400000U;
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
unsigned int bPos = DMR_B_TABLE[i];
if (READ_BIT(bytes, bPos))
b |= MASK;
}
unsigned int c = 0U;
MASK = 0x1000000U;
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
unsigned int cPos = DMR_C_TABLE[i];
if (READ_BIT(bytes, cPos))
c |= MASK;
}
unsigned int errors = regenerateDMR(a, b);
MASK = 0x800000U;
for (unsigned int i = 0U; i < 24U; i++) {
for (unsigned int i = 0U; i < 24U; i++, MASK >>= 1) {
unsigned int aPos = DMR_A_TABLE[i];
unsigned int bPos = DMR_B_TABLE[i];
unsigned int cPos = DMR_C_TABLE[i];
WRITE_BIT(bytes, aPos, a & MASK);
WRITE_BIT(bytes, bPos, b & MASK);
WRITE_BIT(bytes, cPos, c & MASK);
}
MASK >>= 1;
MASK = 0x400000U;
for (unsigned int i = 0U; i < 23U; i++, MASK >>= 1) {
unsigned int bPos = DMR_B_TABLE[i];
WRITE_BIT(bytes, bPos, b & MASK);
}
MASK = 0x1000000U;
for (unsigned int i = 0U; i < 25U; i++, MASK >>= 1) {
unsigned int cPos = DMR_C_TABLE[i];
WRITE_BIT(bytes, cPos, c & MASK);
}
return errors;
@ -772,17 +790,14 @@ unsigned int CAMBEFEC::regenerateIMBE(unsigned char* bytes) const
return errors;
}
unsigned int CAMBEFEC::regenerate(unsigned int& a, unsigned int& b, unsigned int& c, bool b23) const
unsigned int CAMBEFEC::regenerateDStar(unsigned int& a, unsigned int& b) const
{
unsigned int old_a = a;
unsigned int old_b = b;
// For the b23 bypass
bool b24 = (b & 0x01U) == 0x01U;
unsigned int orig_a = a;
unsigned int orig_b = b;
unsigned int data = CGolay24128::decode24128(a);
unsigned int new_a = CGolay24128::encode24128(data);
a = CGolay24128::encode24128(data);
// The PRNG
unsigned int p = PRNG_TABLE[data];
@ -791,39 +806,60 @@ unsigned int CAMBEFEC::regenerate(unsigned int& a, unsigned int& b, unsigned int
unsigned int datb = CGolay24128::decode24128(b);
unsigned int new_b = CGolay24128::encode24128(datb);
b = CGolay24128::encode24128(datb);
new_b ^= p;
if (b23) {
new_b &= 0xFFFFFEU;
new_b |= b24 ? 0x01U : 0x00U;
}
b ^= p;
unsigned int errsA = 0U, errsB = 0U;
unsigned int v = new_a ^ old_a;
unsigned int v = a ^ orig_a;
while (v != 0U) {
v &= v - 1U;
errsA++;
}
v = new_b ^ old_b;
v = b ^ orig_b;
while (v != 0U) {
v &= v - 1U;
errsB++;
}
if (b23) {
if (errsA >= 4U || ((errsA + errsB) >= 6U && errsA >= 2U)) {
a = 0xF00292U;
b = 0x0E0B20U;
c = 0x000000U;
}
return errsA + errsB;
}
unsigned int CAMBEFEC::regenerateDMR(unsigned int& a, unsigned int& b) const
{
unsigned int orig_a = a;
unsigned int orig_b = b;
unsigned int data = CGolay24128::decode24128(a);
a = CGolay24128::encode24128(data);
// The PRNG
unsigned int p = PRNG_TABLE[data] >> 1;
b ^= p;
unsigned int datb = CGolay24128::decode23127(b);
b = CGolay24128::encode23127(datb) >> 1;
b ^= p;
unsigned int errsA = 0U, errsB = 0U;
unsigned int v = a ^ orig_a;
while (v != 0U) {
v &= v - 1U;
errsA++;
}
a = new_a;
b = new_b;
v = b ^ orig_b;
while (v != 0U) {
v &= v - 1U;
errsB++;
}
return errsA + errsB;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010,2014,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2010,2014,2016,2018 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -33,7 +33,8 @@ public:
unsigned int regenerateIMBE(unsigned char* bytes) const;
private:
unsigned int regenerate(unsigned int& a, unsigned int& b, unsigned int& c, bool b23) const;
unsigned int regenerateDStar(unsigned int& a, unsigned int& b) const;
unsigned int regenerateDMR(unsigned int& a, unsigned int& b) const;
};
#endif