mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-10-31 15:07:12 -04:00
111 lines
2.2 KiB
C++
111 lines
2.2 KiB
C++
// Copyright 2020 Rob Riggs <rob@mobilinkd.com>
|
|
// All rights reserved.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
#include "export.h"
|
|
|
|
namespace modemm17 {
|
|
|
|
// Parts are adapted from:
|
|
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
|
|
|
|
|
|
namespace Golay24_detail
|
|
{
|
|
|
|
// Need a constexpr sort.
|
|
// https://stackoverflow.com/a/40030044/854133
|
|
template<class T>
|
|
static void swap(T& l, T& r)
|
|
{
|
|
T tmp = std::move(l);
|
|
l = std::move(r);
|
|
r = std::move(tmp);
|
|
}
|
|
|
|
template <typename T, size_t N>
|
|
struct array
|
|
{
|
|
constexpr T& operator[](size_t i) {
|
|
return arr[i];
|
|
}
|
|
|
|
constexpr const T& operator[](size_t i) const {
|
|
return arr[i];
|
|
}
|
|
|
|
constexpr const T* begin() const {
|
|
return arr;
|
|
}
|
|
|
|
constexpr const T* end() const {
|
|
return arr + N;
|
|
}
|
|
|
|
T arr[N];
|
|
};
|
|
|
|
template <typename T, size_t N>
|
|
static void sort_impl(array<T, N> &array, size_t left, size_t right)
|
|
{
|
|
if (left < right)
|
|
{
|
|
size_t m = left;
|
|
|
|
for (size_t i = left + 1; i<right; i++)
|
|
if (array[i]<array[left])
|
|
swap(array[++m], array[i]);
|
|
|
|
swap(array[left], array[m]);
|
|
|
|
sort_impl(array, left, m);
|
|
sort_impl(array, m + 1, right);
|
|
}
|
|
}
|
|
|
|
template <typename T, size_t N>
|
|
static array<T, N> sort(array<T, N> array)
|
|
{
|
|
auto sorted = array;
|
|
sort_impl(sorted, 0, N);
|
|
return sorted;
|
|
}
|
|
|
|
} // Golay24_detail
|
|
|
|
|
|
struct MODEMM17_API Golay24
|
|
{
|
|
#pragma pack(push, 1)
|
|
struct SyndromeMapEntry
|
|
{
|
|
uint32_t a{0};
|
|
uint16_t b{0};
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static const uint16_t POLY = 0xC75;
|
|
static const size_t LUT_SIZE = 2048;
|
|
static std::array<SyndromeMapEntry, LUT_SIZE> LUT;
|
|
|
|
Golay24();
|
|
static uint32_t encode23(uint16_t data);
|
|
static uint32_t encode24(uint16_t data);
|
|
static bool decode(uint32_t input, uint32_t& output);
|
|
|
|
private:
|
|
static bool parity(uint32_t codeword);
|
|
static SyndromeMapEntry makeSyndromeMapEntry(uint64_t val);
|
|
static uint32_t syndrome(uint32_t codeword);
|
|
static uint64_t makeSME(uint64_t syndrome, uint32_t bits);
|
|
static std::array<SyndromeMapEntry, LUT_SIZE> make_lut();
|
|
};
|
|
|
|
} // modemm17
|