Line data Source code
1 : /*
2 : * libpoporon - ldpc.h
3 : *
4 : * This file is part of libpoporon.
5 : *
6 : * Author: Go Kudo <zeriyoshi@gmail.com>
7 : * SPDX-License-Identifier: BSD-3-Clause
8 : */
9 :
10 : #ifndef POPORON_INTERNAL_LDPC_H
11 : #define POPORON_INTERNAL_LDPC_H
12 :
13 : #include "common.h"
14 :
15 : #define LLR_MAX ((int16_t)32000)
16 : #define LLR_MIN ((int16_t)-32000)
17 : #define LLR_INFINITY ((int16_t)30000)
18 :
19 : typedef struct {
20 : poporon_ldpc_matrix_type_t matrix_type;
21 : uint32_t column_weight;
22 : bool use_inner_interleave;
23 : bool use_outer_interleave;
24 : uint32_t interleave_depth;
25 : uint32_t lifting_factor;
26 : uint64_t seed;
27 : } poporon_ldpc_params_t;
28 :
29 : typedef struct {
30 : uint32_t *row_ptr;
31 : uint32_t *col_idx;
32 : uint32_t num_checks;
33 : uint32_t num_bits;
34 : uint32_t num_edges;
35 : } sparse_matrix_t;
36 :
37 : typedef struct {
38 : uint32_t *col_ptr;
39 : uint32_t *row_idx;
40 : uint32_t *edge_idx;
41 : } column_view_t;
42 :
43 : typedef struct {
44 : int16_t *check_to_var;
45 : int16_t *var_to_check;
46 : int16_t *llr_total;
47 : } messages_t;
48 :
49 : typedef struct {
50 : uint32_t *forward;
51 : uint32_t *inverse;
52 : size_t size;
53 : uint32_t depth;
54 : } interleaver_t;
55 :
56 : typedef struct {
57 : uint32_t *forward;
58 : uint32_t *inverse;
59 : size_t size;
60 : } outer_interleaver_t;
61 :
62 : struct _poporon_ldpc_t {
63 : poporon_ldpc_rate_t rate;
64 : poporon_ldpc_params_t config;
65 : size_t info_bits;
66 : size_t parity_bits;
67 : size_t codeword_bits;
68 : size_t info_bytes;
69 : size_t parity_bytes;
70 : size_t codeword_bytes;
71 :
72 : sparse_matrix_t parity_matrix;
73 : column_view_t parity_matrix_cols;
74 : messages_t msg;
75 : interleaver_t interleaver;
76 : outer_interleaver_t outer_interleaver;
77 :
78 : uint8_t *temp_codeword;
79 : uint8_t *temp_interleaved;
80 : uint8_t *temp_outer;
81 : };
82 :
83 : poporon_ldpc_t *poporon_ldpc_create(size_t block_size, poporon_ldpc_rate_t rate, const poporon_ldpc_params_t *config);
84 : void poporon_ldpc_destroy(poporon_ldpc_t *ldpc);
85 :
86 : bool poporon_ldpc_params_default(poporon_ldpc_params_t *config);
87 : bool poporon_ldpc_params_burst_resistant(poporon_ldpc_params_t *config);
88 :
89 : size_t poporon_ldpc_info_size(const poporon_ldpc_t *ldpc);
90 : size_t poporon_ldpc_codeword_size(const poporon_ldpc_t *ldpc);
91 : size_t poporon_ldpc_parity_size(const poporon_ldpc_t *ldpc);
92 :
93 : bool poporon_ldpc_encode(poporon_ldpc_t *ldpc, const uint8_t *info, uint8_t *parity);
94 : bool poporon_ldpc_decode_hard(poporon_ldpc_t *ldpc, uint8_t *codeword, uint32_t max_iterations,
95 : uint32_t *iterations_used);
96 : bool poporon_ldpc_decode_soft(poporon_ldpc_t *ldpc, const int8_t *llr, uint8_t *codeword, uint32_t max_iterations,
97 : uint32_t *iterations_used);
98 :
99 : bool poporon_ldpc_check(const poporon_ldpc_t *ldpc, const uint8_t *codeword);
100 : bool poporon_ldpc_has_interleaver(const poporon_ldpc_t *ldpc);
101 :
102 : bool poporon_ldpc_interleave(const poporon_ldpc_t *ldpc, const uint8_t *input, uint8_t *output);
103 : bool poporon_ldpc_deinterleave(const poporon_ldpc_t *ldpc, const uint8_t *input, uint8_t *output);
104 :
105 887749 : static inline int16_t ldpc_saturate(int32_t val)
106 : {
107 887749 : if (val > LLR_MAX) {
108 430687 : return LLR_MAX;
109 457062 : } else if (val < LLR_MIN) {
110 428641 : return LLR_MIN;
111 : }
112 :
113 28421 : return (int16_t)val;
114 : }
115 :
116 : static inline int16_t ldpc_abs(int16_t val)
117 : {
118 : return (val < 0) ? -val : val;
119 : }
120 :
121 : static inline int16_t ldpc_sign(int16_t val)
122 : {
123 : return (val < 0) ? -1 : 1;
124 : }
125 :
126 : static inline int16_t ldpc_min(int16_t a, int16_t b)
127 : {
128 : return (a < b) ? a : b;
129 : }
130 :
131 : #endif /* POPORON_INTERNAL_LDPC_H */
|