1 /*
2 FILE...: ldpc_codes.c
3 AUTHOR.: David Rowe
4 CREATED: July 2020
5
6 Array of LDPC codes used for various Codec2 waveforms.
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include "assert.h"
12 #include "ldpc_codes.h"
13 #include "interldpc.h"
14 #include "H_2064_516_sparse.h"
15 #include "HRA_112_112.h"
16 #include "HRAb_396_504.h"
17 #include "H_256_768_22.h"
18 #include "H_256_512_4.h"
19 #include "HRAa_1536_512.h"
20 #include "H_128_256_5.h"
21 #include "HRA_56_56.h"
22 #include "H_4096_8192_3d.h"
23 #include "H_16200_9720.h"
24 #include "H_1024_2048_4f.h"
25
26 struct LDPC ldpc_codes[] = {
27 /* short rate 1/2 code for FreeDV 700D */
28 {
29 "HRA_112_112",
30 HRA_112_112_MAX_ITER,
31 0,
32 1,
33 1,
34 HRA_112_112_CODELENGTH,
35 HRA_112_112_NUMBERPARITYBITS,
36 HRA_112_112_NUMBERROWSHCOLS,
37 HRA_112_112_MAX_ROW_WEIGHT,
38 HRA_112_112_MAX_COL_WEIGHT,
39 (uint16_t *)HRA_112_112_H_rows,
40 (uint16_t *)HRA_112_112_H_cols
41 }
42 ,
43 /* short rate 1/2 code for FreeDV 700E */
44 {
45 "HRA_56_56",
46 HRA_56_56_MAX_ITER,
47 0,
48 1,
49 1,
50 HRA_56_56_CODELENGTH,
51 HRA_56_56_NUMBERPARITYBITS,
52 HRA_56_56_NUMBERROWSHCOLS,
53 HRA_56_56_MAX_ROW_WEIGHT,
54 HRA_56_56_MAX_COL_WEIGHT,
55 (uint16_t *)HRA_56_56_H_rows,
56 (uint16_t *)HRA_56_56_H_cols
57 },
58 #ifndef __EMBEDDED__
59
60 /* default Wenet High Alitiude Balloon rate 0.8 code */
61 {
62 "H_2064_516_sparse",
63 MAX_ITER,
64 0,
65 1,
66 1,
67 CODELENGTH,
68 NUMBERPARITYBITS,
69 NUMBERROWSHCOLS,
70 MAX_ROW_WEIGHT,
71 MAX_COL_WEIGHT,
72 (uint16_t *)H_2064_516_sparse_H_rows,
73 (uint16_t *)H_2064_516_sparse_H_cols
74 },
75
76 /* rate 0.8 code used for FreeDV 2020 */
77 {
78 "HRAb_396_504",
79 HRAb_396_504_MAX_ITER,
80 0,
81 1,
82 1,
83 HRAb_396_504_CODELENGTH,
84 HRAb_396_504_NUMBERPARITYBITS,
85 HRAb_396_504_NUMBERROWSHCOLS,
86 HRAb_396_504_MAX_ROW_WEIGHT,
87 HRAb_396_504_MAX_COL_WEIGHT,
88 (uint16_t *)HRAb_396_504_H_rows,
89 (uint16_t *)HRAb_396_504_H_cols
90 },
91
92 /* rate 1/3 code, works at raw BER of 14% */
93 {
94 "H_256_768_22",
95 H_256_768_22_MAX_ITER,
96 0,
97 1,
98 1,
99 H_256_768_22_CODELENGTH,
100 H_256_768_22_NUMBERPARITYBITS,
101 H_256_768_22_NUMBERROWSHCOLS,
102 H_256_768_22_MAX_ROW_WEIGHT,
103 H_256_768_22_MAX_COL_WEIGHT,
104 (uint16_t *)H_256_768_22_H_rows,
105 (uint16_t *)H_256_768_22_H_cols
106 },
107
108 /* used for 4FSK/LLR experiments */
109 {
110 "H_256_512_4",
111 H_256_512_4_MAX_ITER,
112 0,
113 1,
114 1,
115 H_256_512_4_CODELENGTH,
116 H_256_512_4_NUMBERPARITYBITS,
117 H_256_512_4_NUMBERROWSHCOLS,
118 H_256_512_4_MAX_ROW_WEIGHT,
119 H_256_512_4_MAX_COL_WEIGHT,
120 (uint16_t *)H_256_512_4_H_rows,
121 (uint16_t *)H_256_512_4_H_cols
122 },
123
124 /* used for 4FSK/LLR experiments */
125 {
126 "HRAa_1536_512",
127 HRAa_1536_512_MAX_ITER,
128 0,
129 1,
130 1,
131 HRAa_1536_512_CODELENGTH,
132 HRAa_1536_512_NUMBERPARITYBITS,
133 HRAa_1536_512_NUMBERROWSHCOLS,
134 HRAa_1536_512_MAX_ROW_WEIGHT,
135 HRAa_1536_512_MAX_COL_WEIGHT,
136 (uint16_t *)HRAa_1536_512_H_rows,
137 (uint16_t *)HRAa_1536_512_H_cols
138 },
139
140 /* used for 4FSK/LLR experiments */
141 {
142 "H_128_256_5",
143 H_128_256_5_MAX_ITER,
144 0,
145 1,
146 1,
147 H_128_256_5_CODELENGTH,
148 H_128_256_5_NUMBERPARITYBITS,
149 H_128_256_5_NUMBERROWSHCOLS,
150 H_128_256_5_MAX_ROW_WEIGHT,
151 H_128_256_5_MAX_COL_WEIGHT,
152 (uint16_t *)H_128_256_5_H_rows,
153 (uint16_t *)H_128_256_5_H_cols
154 },
155
156 /* Nice long code from Bill VK5DSP - useful for HF data */
157 {
158 "H_4096_8192_3d",
159 H_4096_8192_3d_MAX_ITER,
160 0,
161 1,
162 1,
163 H_4096_8192_3d_CODELENGTH,
164 H_4096_8192_3d_NUMBERPARITYBITS,
165 H_4096_8192_3d_NUMBERROWSHCOLS,
166 H_4096_8192_3d_MAX_ROW_WEIGHT,
167 H_4096_8192_3d_MAX_COL_WEIGHT,
168 (uint16_t *)H_4096_8192_3d_H_rows,
169 (uint16_t *)H_4096_8192_3d_H_cols
170 },
171
172 /* Nice long code from Bill VK5DSP - useful for HF data */
173 {
174 "H_16200_9720",
175 H_16200_9720_MAX_ITER,
176 0,
177 1,
178 1,
179 H_16200_9720_CODELENGTH,
180 H_16200_9720_NUMBERPARITYBITS,
181 H_16200_9720_NUMBERROWSHCOLS,
182 H_16200_9720_MAX_ROW_WEIGHT,
183 H_16200_9720_MAX_COL_WEIGHT,
184 (uint16_t *)H_16200_9720_H_rows,
185 (uint16_t *)H_16200_9720_H_cols
186 },
187
188 /* Another fine code from Bill VK5DSK - also useful for HF data */
189 {
190 "H_1024_2048_4f",
191 H_1024_2048_4f_MAX_ITER,
192 0,
193 1,
194 1,
195 H_1024_2048_4f_CODELENGTH,
196 H_1024_2048_4f_NUMBERPARITYBITS,
197 H_1024_2048_4f_NUMBERROWSHCOLS,
198 H_1024_2048_4f_MAX_ROW_WEIGHT,
199 H_1024_2048_4f_MAX_COL_WEIGHT,
200 (uint16_t *)H_1024_2048_4f_H_rows,
201 (uint16_t *)H_1024_2048_4f_H_cols
202 }
203 #endif
204 };
205
ldpc_codes_num(void)206 int ldpc_codes_num(void) { return sizeof(ldpc_codes)/sizeof(struct LDPC); }
207
ldpc_codes_list()208 void ldpc_codes_list() {
209 fprintf(stderr, "\n");
210 for(int c=0; c<ldpc_codes_num(); c++) {
211 int n = ldpc_codes[c].NumberRowsHcols + ldpc_codes[c].NumberParityBits;
212 int k = ldpc_codes[c].NumberRowsHcols;
213 float rate = (float)k/n;
214 fprintf(stderr, "%-20s rate %3.2f (%d,%d) \n", ldpc_codes[c].name, (double)rate, n, k);
215 }
216 fprintf(stderr, "\n");
217 }
218
ldpc_codes_find(char name[])219 int ldpc_codes_find(char name[]) {
220 int code_index = -1;
221 for(int c=0; c<ldpc_codes_num(); c++)
222 if (strcmp(ldpc_codes[c].name, name) == 0)
223 code_index = c;
224 assert(code_index != -1); /* code not found */
225 return code_index;
226 }
227
ldpc_codes_setup(struct LDPC * ldpc,char name[])228 void ldpc_codes_setup(struct LDPC *ldpc, char name[]) {
229 int code_index;
230 code_index = ldpc_codes_find(name);
231 assert(code_index != -1);
232 memcpy(ldpc,&ldpc_codes[code_index], sizeof(struct LDPC));
233 set_up_ldpc_constants(ldpc, ldpc->CodeLength, ldpc->NumberParityBits);
234 }
235