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