mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-12 01:29:29 +00:00
Added tetra rx ext app (#3257)
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
#include "tetra_viterbi.hpp"
|
||||
#include <string.h>
|
||||
|
||||
namespace ui::external_app::tetra_rx {
|
||||
|
||||
int Viterbi::decode_cch(
|
||||
const uint8_t* mother,
|
||||
uint32_t n_info,
|
||||
uint8_t* bits,
|
||||
uint8_t* trace_buffer) { // Puffer by caller
|
||||
|
||||
// Store these on stack, to avoid flash space usage
|
||||
const uint8_t next_state[16][2] = {
|
||||
{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}};
|
||||
const uint8_t next_output[16][2] = {
|
||||
{0, 15}, {11, 4}, {6, 9}, {13, 2}, {5, 10}, {14, 1}, {3, 12}, {8, 7}, {15, 0}, {4, 11}, {9, 6}, {2, 13}, {10, 5}, {1, 14}, {12, 3}, {7, 8}};
|
||||
|
||||
const uint16_t INF = 0x3fff;
|
||||
uint16_t cost[16];
|
||||
uint16_t new_cost[16];
|
||||
|
||||
// Initialization
|
||||
for (int i = 0; i < 16; i++) cost[i] = INF;
|
||||
cost[0] = 0;
|
||||
|
||||
for (uint32_t step = 0; step < n_info; step++) {
|
||||
for (int i = 0; i < 16; i++) new_cost[i] = INF;
|
||||
const uint8_t* rx = &mother[step * 4];
|
||||
|
||||
for (int prev = 0; prev < 16; prev++) {
|
||||
if (cost[prev] >= INF) continue;
|
||||
|
||||
for (int bit = 0; bit < 2; bit++) {
|
||||
const uint8_t pattern = next_output[prev][bit];
|
||||
const uint8_t next = next_state[prev][bit];
|
||||
|
||||
uint16_t d = 0;
|
||||
for (int b = 0; b < 4; b++) {
|
||||
if (rx[b] != 0xff && rx[b] != ((pattern >> (3 - b)) & 1)) d++;
|
||||
}
|
||||
|
||||
const uint16_t total = cost[prev] + d;
|
||||
if (total < new_cost[next]) {
|
||||
new_cost[next] = total;
|
||||
trace_buffer[step * 16 + next] = (prev << 1) | bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(cost, new_cost, sizeof(cost));
|
||||
}
|
||||
|
||||
// Traceback
|
||||
uint8_t best_state = 0;
|
||||
for (int i = 1; i < 16; i++) {
|
||||
if (cost[i] < cost[best_state]) best_state = i;
|
||||
}
|
||||
|
||||
uint8_t state = best_state;
|
||||
memset(bits, 0, (n_info + 7) >> 3);
|
||||
|
||||
for (int step = (int)n_info - 1; step >= 0; step--) {
|
||||
uint8_t packed = trace_buffer[step * 16 + state];
|
||||
uint8_t prev = (packed >> 1) & 0x0F;
|
||||
uint8_t bit = packed & 0x01;
|
||||
|
||||
if (bit) bits[step >> 3] |= (1 << (7 - (step & 7)));
|
||||
state = prev;
|
||||
}
|
||||
|
||||
return cost[best_state];
|
||||
}
|
||||
|
||||
} // namespace ui::external_app::tetra_rx
|
||||
Reference in New Issue
Block a user