1 // ----------------------------------------------------------------------------
2 // varicode.cxx -- PSK31 Varicode
3 //
4 // Copyright (C) 2006
5 // Dave Freese, W1HKJ
6 //
7 // This file is part of fldigi. Adapted from code contained in gmfsk source code
8 // distribution.
9 //
10 // Fldigi is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Fldigi is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with fldigi. If not, see <http://www.gnu.org/licenses/>.
22 // ----------------------------------------------------------------------------
23
24
25 #include <config.h>
26
27 #include "pskvaricode.h"
28
29 // PSK31 Varicode for encoding
30
31 static const char *varicodetab1[] = {
32 "1010101011", /* 0 - <NUL> */
33 "1011011011", /* 1 - <SOH> */
34 "1011101101", /* 2 - <STX> */
35 "1101110111", /* 3 - <ETX> */
36 "1011101011", /* 4 - <EOT> */
37 "1101011111", /* 5 - <ENQ> */
38 "1011101111", /* 6 - <ACK> */
39 "1011111101", /* 7 - <BEL> */
40 "1011111111", /* 8 - <BS> */
41 "11101111", /* 9 - <TAB> */
42 "11101", /* 10 - <LF> */
43 "1101101111", /* 11 - <VT> */
44 "1011011101", /* 12 - <FF> */
45 "11111", /* 13 - <CR> */
46 "1101110101", /* 14 - <SO> */
47 "1110101011", /* 15 - <SI> */
48 "1011110111", /* 16 - <DLE> */
49 "1011110101", /* 17 - <DC1> */
50 "1110101101", /* 18 - <DC2> */
51 "1110101111", /* 19 - <DC3> */
52 "1101011011", /* 20 - <DC4> */
53 "1101101011", /* 21 - <NAK> */
54 "1101101101", /* 22 - <SYN> */
55 "1101010111", /* 23 - <ETB> */
56 "1101111011", /* 24 - <CAN> */
57 "1101111101", /* 25 - <EM> */
58 "1110110111", /* 26 - <SUB> */
59 "1101010101", /* 27 - <ESC> */
60 "1101011101", /* 28 - <FS> */
61 "1110111011", /* 29 - <GS> */
62 "1011111011", /* 30 - <RS> */
63 "1101111111", /* 31 - <US> */
64 "1", /* 32 - <SPC> */
65 "111111111", /* 33 - ! */
66 "101011111", /* 34 - '"' */
67 "111110101", /* 35 - # */
68 "111011011", /* 36 - $ */
69 "1011010101", /* 37 - % */
70 "1010111011", /* 38 - & */
71 "101111111", /* 39 - ' */
72 "11111011", /* 40 - ( */
73 "11110111", /* 41 - ) */
74 "101101111", /* 42 - * */
75 "111011111", /* 43 - + */
76 "1110101", /* 44 - , */
77 "110101", /* 45 - - */
78 "1010111", /* 46 - . */
79 "110101111", /* 47 - / */
80 "10110111", /* 48 - 0 */
81 "10111101", /* 49 - 1 */
82 "11101101", /* 50 - 2 */
83 "11111111", /* 51 - 3 */
84 "101110111", /* 52 - 4 */
85 "101011011", /* 53 - 5 */
86 "101101011", /* 54 - 6 */
87 "110101101", /* 55 - 7 */
88 "110101011", /* 56 - 8 */
89 "110110111", /* 57 - 9 */
90 "11110101", /* 58 - : */
91 "110111101", /* 59 - ; */
92 "111101101", /* 60 - < */
93 "1010101", /* 61 - = */
94 "111010111", /* 62 - > */
95 "1010101111", /* 63 - ? */
96 "1010111101", /* 64 - @ */
97 "1111101", /* 65 - A */
98 "11101011", /* 66 - B */
99 "10101101", /* 67 - C */
100 "10110101", /* 68 - D */
101 "1110111", /* 69 - E */
102 "11011011", /* 70 - F */
103 "11111101", /* 71 - G */
104 "101010101", /* 72 - H */
105 "1111111", /* 73 - I */
106 "111111101", /* 74 - J */
107 "101111101", /* 75 - K */
108 "11010111", /* 76 - L */
109 "10111011", /* 77 - M */
110 "11011101", /* 78 - N */
111 "10101011", /* 79 - O */
112 "11010101", /* 80 - P */
113 "111011101", /* 81 - Q */
114 "10101111", /* 82 - R */
115 "1101111", /* 83 - S */
116 "1101101", /* 84 - T */
117 "101010111", /* 85 - U */
118 "110110101", /* 86 - V */
119 "101011101", /* 87 - W */
120 "101110101", /* 88 - X */
121 "101111011", /* 89 - Y */
122 "1010101101", /* 90 - Z */
123 "111110111", /* 91 - [ */
124 "111101111", /* 92 - \ */
125 "111111011", /* 93 - ] */
126 "1010111111", /* 94 - ^ */
127 "101101101", /* 95 - _ */
128 "1011011111", /* 96 - ` */
129 "1011", /* 97 - a */
130 "1011111", /* 98 - b */
131 "101111", /* 99 - c */
132 "101101", /* 100 - d */
133 "11", /* 101 - e */
134 "111101", /* 102 - f */
135 "1011011", /* 103 - g */
136 "101011", /* 104 - h */
137 "1101", /* 105 - i */
138 "111101011", /* 106 - j */
139 "10111111", /* 107 - k */
140 "11011", /* 108 - l */
141 "111011", /* 109 - m */
142 "1111", /* 110 - n */
143 "111", /* 111 - o */
144 "111111", /* 112 - p */
145 "110111111", /* 113 - q */
146 "10101", /* 114 - r */
147 "10111", /* 115 - s */
148 "101", /* 116 - t */
149 "110111", /* 117 - u */
150 "1111011", /* 118 - v */
151 "1101011", /* 119 - w */
152 "11011111", /* 120 - x */
153 "1011101", /* 121 - y */
154 "111010101", /* 122 - z */
155 "1010110111", /* 123 - { */
156 "110111011", /* 124 - | */
157 "1010110101", /* 125 - } */
158 "1011010111", /* 126 - ~ */
159 "1110110101", /* 127 - <DEL> */
160 "1110111101", /* 128 - */
161 "1110111111", /* 129 - */
162 "1111010101", /* 130 - */
163 "1111010111", /* 131 - */
164 "1111011011", /* 132 - */
165 "1111011101", /* 133 - */
166 "1111011111", /* 134 - */
167 "1111101011", /* 135 - */
168 "1111101101", /* 136 - */
169 "1111101111", /* 137 - */
170 "1111110101", /* 138 - */
171 "1111110111", /* 139 - */
172 "1111111011", /* 140 - */
173 "1111111101", /* 141 - */
174 "1111111111", /* 142 - */
175 "10101010101", /* 143 - */
176 "10101010111", /* 144 - */
177 "10101011011", /* 145 - */
178 "10101011101", /* 146 - */
179 "10101011111", /* 147 - */
180 "10101101011", /* 148 - */
181 "10101101101", /* 149 - */
182 "10101101111", /* 150 - */
183 "10101110101", /* 151 - */
184 "10101110111", /* 152 - */
185 "10101111011", /* 153 - */
186 "10101111101", /* 154 - */
187 "10101111111", /* 155 - */
188 "10110101011", /* 156 - */
189 "10110101101", /* 157 - */
190 "10110101111", /* 158 - */
191 "10110110101", /* 159 - */
192 "10110110111", /* 160 - � */
193 "10110111011", /* 161 - � */
194 "10110111101", /* 162 - � */
195 "10110111111", /* 163 - � */
196 "10111010101", /* 164 - � */
197 "10111010111", /* 165 - � */
198 "10111011011", /* 166 - � */
199 "10111011101", /* 167 - � */
200 "10111011111", /* 168 - � */
201 "10111101011", /* 169 - � */
202 "10111101101", /* 170 - � */
203 "10111101111", /* 171 - � */
204 "10111110101", /* 172 - � */
205 "10111110111", /* 173 - � */
206 "10111111011", /* 174 - � */
207 "10111111101", /* 175 - � */
208 "10111111111", /* 176 - � */
209 "11010101011", /* 177 - � */
210 "11010101101", /* 178 - � */
211 "11010101111", /* 179 - � */
212 "11010110101", /* 180 - � */
213 "11010110111", /* 181 - � */
214 "11010111011", /* 182 - � */
215 "11010111101", /* 183 - � */
216 "11010111111", /* 184 - � */
217 "11011010101", /* 185 - � */
218 "11011010111", /* 186 - � */
219 "11011011011", /* 187 - � */
220 "11011011101", /* 188 - � */
221 "11011011111", /* 189 - � */
222 "11011101011", /* 190 - � */
223 "11011101101", /* 191 - � */
224 "11011101111", /* 192 - � */
225 "11011110101", /* 193 - � */
226 "11011110111", /* 194 - � */
227 "11011111011", /* 195 - � */
228 "11011111101", /* 196 - � */
229 "11011111111", /* 197 - � */
230 "11101010101", /* 198 - � */
231 "11101010111", /* 199 - � */
232 "11101011011", /* 200 - � */
233 "11101011101", /* 201 - � */
234 "11101011111", /* 202 - � */
235 "11101101011", /* 203 - � */
236 "11101101101", /* 204 - � */
237 "11101101111", /* 205 - � */
238 "11101110101", /* 206 - � */
239 "11101110111", /* 207 - � */
240 "11101111011", /* 208 - � */
241 "11101111101", /* 209 - � */
242 "11101111111", /* 210 - � */
243 "11110101011", /* 211 - � */
244 "11110101101", /* 212 - � */
245 "11110101111", /* 213 - � */
246 "11110110101", /* 214 - � */
247 "11110110111", /* 215 - � */
248 "11110111011", /* 216 - � */
249 "11110111101", /* 217 - � */
250 "11110111111", /* 218 - � */
251 "11111010101", /* 219 - � */
252 "11111010111", /* 220 - � */
253 "11111011011", /* 221 - � */
254 "11111011101", /* 222 - � */
255 "11111011111", /* 223 - � */
256 "11111101011", /* 224 - � */
257 "11111101101", /* 225 - � */
258 "11111101111", /* 226 - � */
259 "11111110101", /* 227 - � */
260 "11111110111", /* 228 - � */
261 "11111111011", /* 229 - � */
262 "11111111101", /* 230 - � */
263 "11111111111", /* 231 - � */
264 "101010101011", /* 232 - � */
265 "101010101101", /* 233 - � */
266 "101010101111", /* 234 - � */
267 "101010110101", /* 235 - � */
268 "101010110111", /* 236 - � */
269 "101010111011", /* 237 - � */
270 "101010111101", /* 238 - � */
271 "101010111111", /* 239 - � */
272 "101011010101", /* 240 - � */
273 "101011010111", /* 241 - � */
274 "101011011011", /* 242 - � */
275 "101011011101", /* 243 - � */
276 "101011011111", /* 244 - � */
277 "101011101011", /* 245 - � */
278 "101011101101", /* 246 - � */
279 "101011101111", /* 247 - � */
280 "101011110101", /* 248 - � */
281 "101011110111", /* 249 - � */
282 "101011111011", /* 250 - � */
283 "101011111101", /* 251 - � */
284 "101011111111", /* 252 - � */
285 "101101010101", /* 253 - � */
286 "101101010111", /* 254 - � */
287 "101101011011" /* 255 - � */
288 };
289
290 // The same in a format more suitable for decoding.
291
292 static unsigned int varicodetab2[] = {
293 0x2AB, 0x2DB, 0x2ED, 0x377, 0x2EB, 0x35F, 0x2EF, 0x2FD,
294 0x2FF, 0x0EF, 0x01D, 0x36F, 0x2DD, 0x01F, 0x375, 0x3AB,
295 0x2F7, 0x2F5, 0x3AD, 0x3AF, 0x35B, 0x36B, 0x36D, 0x357,
296 0x37B, 0x37D, 0x3B7, 0x355, 0x35D, 0x3BB, 0x2FB, 0x37F,
297 0x001, 0x1FF, 0x15F, 0x1F5, 0x1DB, 0x2D5, 0x2BB, 0x17F,
298 0x0FB, 0x0F7, 0x16F, 0x1DF, 0x075, 0x035, 0x057, 0x1AF,
299 0x0B7, 0x0BD, 0x0ED, 0x0FF, 0x177, 0x15B, 0x16B, 0x1AD,
300 0x1AB, 0x1B7, 0x0F5, 0x1BD, 0x1ED, 0x055, 0x1D7, 0x2AF,
301 0x2BD, 0x07D, 0x0EB, 0x0AD, 0x0B5, 0x077, 0x0DB, 0x0FD,
302 0x155, 0x07F, 0x1FD, 0x17D, 0x0D7, 0x0BB, 0x0DD, 0x0AB,
303 0x0D5, 0x1DD, 0x0AF, 0x06F, 0x06D, 0x157, 0x1B5, 0x15D,
304 0x175, 0x17B, 0x2AD, 0x1F7, 0x1EF, 0x1FB, 0x2BF, 0x16D,
305 0x2DF, 0x00B, 0x05F, 0x02F, 0x02D, 0x003, 0x03D, 0x05B,
306 0x02B, 0x00D, 0x1EB, 0x0BF, 0x01B, 0x03B, 0x00F, 0x007,
307 0x03F, 0x1BF, 0x015, 0x017, 0x005, 0x037, 0x07B, 0x06B,
308 0x0DF, 0x05D, 0x1D5, 0x2B7, 0x1BB, 0x2B5, 0x2D7, 0x3B5,
309 0x3BD, 0x3BF, 0x3D5, 0x3D7, 0x3DB, 0x3DD, 0x3DF, 0x3EB,
310 0x3ED, 0x3EF, 0x3F5, 0x3F7, 0x3FB, 0x3FD, 0x3FF, 0x555,
311 0x557, 0x55B, 0x55D, 0x55F, 0x56B, 0x56D, 0x56F, 0x575,
312 0x577, 0x57B, 0x57D, 0x57F, 0x5AB, 0x5AD, 0x5AF, 0x5B5,
313 0x5B7, 0x5BB, 0x5BD, 0x5BF, 0x5D5, 0x5D7, 0x5DB, 0x5DD,
314 0x5DF, 0x5EB, 0x5ED, 0x5EF, 0x5F5, 0x5F7, 0x5FB, 0x5FD,
315 0x5FF, 0x6AB, 0x6AD, 0x6AF, 0x6B5, 0x6B7, 0x6BB, 0x6BD,
316 0x6BF, 0x6D5, 0x6D7, 0x6DB, 0x6DD, 0x6DF, 0x6EB, 0x6ED,
317 0x6EF, 0x6F5, 0x6F7, 0x6FB, 0x6FD, 0x6FF, 0x755, 0x757,
318 0x75B, 0x75D, 0x75F, 0x76B, 0x76D, 0x76F, 0x775, 0x777,
319 0x77B, 0x77D, 0x77F, 0x7AB, 0x7AD, 0x7AF, 0x7B5, 0x7B7,
320 0x7BB, 0x7BD, 0x7BF, 0x7D5, 0x7D7, 0x7DB, 0x7DD, 0x7DF,
321 0x7EB, 0x7ED, 0x7EF, 0x7F5, 0x7F7, 0x7FB, 0x7FD, 0x7FF,
322 0xAAB, 0xAAD, 0xAAF, 0xAB5, 0xAB7, 0xABB, 0xABD, 0xABF,
323 0xAD5, 0xAD7, 0xADB, 0xADD, 0xADF, 0xAEB, 0xAED, 0xAEF,
324 0xAF5, 0xAF7, 0xAFB, 0xAFD, 0xAFF, 0xB55, 0xB57, 0xB5B
325 };
326
psk_varicode_encode(unsigned char c)327 const char *psk_varicode_encode(unsigned char c)
328 {
329 return varicodetab1[c];
330 }
331
psk_varicode_decode(unsigned int symbol)332 int psk_varicode_decode(unsigned int symbol)
333 {
334 for (int i = 0; i < 256; i++)
335 if (symbol == varicodetab2[i])
336 return i;
337 return -1;
338 }
339
340
341