| 
									
										
										
										
											2022-07-20 09:07:00 +02:00
										 |  |  | // Copyright 2020-2021 Mobilinkd LLC.
 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // make CXXFLAGS="$(pkg-config --cflags gtest) $(pkg-config --libs gtest) -I. -O3" tests/TrellisTest
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <array>
 | 
					
						
							|  |  |  | #include <cstdlib>
 | 
					
						
							|  |  |  | #include <cstdint>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-04 23:03:07 +02:00
										 |  |  | namespace modemm17 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-20 05:47:48 +02:00
										 |  |  | inline std::array<int8_t, 61> make_p1() { | 
					
						
							| 
									
										
										
										
											2022-06-09 04:49:41 +02:00
										 |  |  |     std::array<int8_t, 61> 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; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | /// Puncture matrix for LSF
 | 
					
						
							|  |  |  | constexpr auto P1 = std::array<int8_t, 61>{ | 
					
						
							|  |  |  |     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
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 07:01:42 +02:00
										 |  |  | /// Puncture matrix for audio and BERT frames. Rate 11/12.
 | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | constexpr auto P2 = std::array<int8_t, 12>{ | 
					
						
							|  |  |  |     1, 1, 1, 1, 1, 1, | 
					
						
							|  |  |  |     1, 1, 1, 1, 1, 0}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Puncture matrix for packet frames (7/8).
 | 
					
						
							|  |  |  | constexpr auto P3 = std::array<int8_t, 8>{ | 
					
						
							| 
									
										
										
										
											2022-06-09 04:49:41 +02:00
										 |  |  |     1, 1, 1, 1, 1, 1, 1, 0}; | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 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 <size_t N> | 
					
						
							|  |  |  | constexpr std::array<uint8_t, N> toBitArray(int8_t value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     std::array<uint8_t, N> result{}; | 
					
						
							|  |  |  |     for (size_t i = 0; i != N; ++i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         result[N - (i + 1)] = (value & 1); | 
					
						
							|  |  |  |         value >>= 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <size_t N> | 
					
						
							|  |  |  | struct NextStateTable | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     using nextStateTable_t = std::array<std::array<int8_t, N>, 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 <size_t K, size_t N, size_t LLR = 1> | 
					
						
							|  |  |  | struct CostTable | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static constexpr int8_t Price = 1 << LLR; | 
					
						
							|  |  |  |     static constexpr size_t InputValues = 1 << N; | 
					
						
							|  |  |  |     using cost_table_t = std::array<std::array<uint8_t, InputValues>, K>; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Only valid for a k=1 (1:n) convolutional coder. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | template <size_t K_, size_t n_> | 
					
						
							|  |  |  | 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<uint32_t, n_>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     polynomials_t polynomials; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 05:56:06 +02:00
										 |  |  |     Trellis(polynomials_t polys) : | 
					
						
							|  |  |  |         polynomials(polys) | 
					
						
							| 
									
										
										
										
											2022-06-07 03:22:18 +02:00
										 |  |  |     {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <size_t K, size_t n> | 
					
						
							|  |  |  | constexpr Trellis<K, n> makeTrellis(std::array<uint32_t, n> polys) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return Trellis<K, n>(polys); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-04 23:03:07 +02:00
										 |  |  | } // modemm17
 |