// Copyright 2020-2021 Mobilinkd LLC. // make CXXFLAGS="$(pkg-config --cflags gtest) $(pkg-config --libs gtest) -I. -O3" tests/TrellisTest #pragma once #include #include #include namespace modemm17 { inline std::array make_p1() { std::array result{}; for (size_t i = 0, j = 2; i != 61; ++i) { if (i == j) { result[i] = 0; j += 4; } else { result[i] = 1; } } return result; }; /// Puncture matrix for LSF constexpr auto P1 = std::array{ 1, 1, 0, 1, 1, // M1 1, 0, 1, 1, // M2 1, 0, 1, 1, // M3 1, 0, 1, 1, // M4 1, 0, 1, 1, // M5 1, 0, 1, 1, // M6 1, 0, 1, 1, // M7 1, 0, 1, 1, // M8 1, 0, 1, 1, // M9 1, 0, 1, 1, // M10 1, 0, 1, 1, // M10 1, 0, 1, 1, // M12 1, 0, 1, 1, // M13 1, 0, 1, 1, // M14 1, 0, 1, 1 // M15 }; /// Puncture matrix for audio and BERT frames. Rate 11/12. constexpr auto P2 = std::array{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; /// Puncture matrix for packet frames (7/8). constexpr auto P3 = std::array{ 1, 1, 1, 1, 1, 1, 1, 0}; /** * Convert an integer value to an array of bits, with the * high-bit at index 0. * * At anything beyond -O0, the array is constructed at compile time. */ template constexpr std::array toBitArray(int8_t value) { std::array result{}; for (size_t i = 0; i != N; ++i) { result[N - (i + 1)] = (value & 1); value >>= 1; } return result; } template struct NextStateTable { using nextStateTable_t = std::array, N>; nextStateTable_t nextStateTable = makeNextStateTable(); static constexpr nextStateTable_t makeNextStateTable() { return nextStateTable_t(); } }; /** * Compute a cost table for a Trellis of size K, for input n of N, * and LLR size of LLR bits + 1. (i.e. LLR = 1 allows 2 bits to * represent -1, 0, +1). */ template struct CostTable { static constexpr int8_t Price = 1 << LLR; static constexpr size_t InputValues = 1 << N; using cost_table_t = std::array, K>; }; /** * Only valid for a k=1 (1:n) convolutional coder. */ template struct Trellis { static constexpr size_t K = K_; // Memory depth of convolution. static constexpr size_t k = 1; // Number of bits per input symbol. static constexpr size_t n = n_; // Number of coefficients / output bits. static constexpr size_t NumStates = (1 << K); // Number of states in the convolutional coder. using polynomials_t = std::array; polynomials_t polynomials; Trellis(polynomials_t polys) : polynomials(polys) {} }; template constexpr Trellis makeTrellis(std::array polys) { return Trellis(polys); } } // modemm17