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