1 // ----------------------------------------------------------------------------
2 //
3 //	MFSKvaricode.cxx  --  MFSK Varicode
4 //
5 // Copyright (C) 2006-2007
6 //		Dave Freese, W1HKJ
7 //
8 // This file is part of fldigi.  Adapted from code contained in gmfsk source code
9 // distribution.
10 //
11 // This file is part of fldigi.
12 //
13 // Fldigi is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // Fldigi is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with fldigi.  If not, see <http://www.gnu.org/licenses/>.
25 // ----------------------------------------------------------------------------
26 
27 #include <config.h>
28 
29 #include "mfskvaricode.h"
30 
31 /*
32  * The IZ8BLY MFSK Varicode as defined in
33  *   http://www.qsl.net/zl1bpu/MFSK/Varicode.html
34  */
35 static const char *varicode[] = {
36 	"11101011100",		/* 000 - <NUL>	*/
37 	"11101100000",		/* 001 - <SOH>	*/
38 	"11101101000",		/* 002 - <STX>	*/
39 	"11101101100",		/* 003 - <ETX>	*/
40 	"11101110000",		/* 004 - <EOT>	*/
41 	"11101110100",		/* 005 - <ENQ>	*/
42 	"11101111000",		/* 006 - <ACK>	*/
43 	"11101111100",		/* 007 - <BEL>	*/
44 	"10101000",			/* 008 - <BS>	*/
45 	"11110000000",		/* 009 - <TAB>	*/
46 	"11110100000",		/* 010 - <LF>	*/
47 	"11110101000",		/* 011 - <VT>	*/
48 	"11110101100",		/* 012 - <FF>	*/
49 	"10101100",			/* 013 - <CR>	*/
50 	"11110110000",		/* 014 - <SO>	*/
51 	"11110110100",		/* 015 - <SI>	*/
52 	"11110111000",		/* 016 - <DLE>	*/
53 	"11110111100",		/* 017 - <DC1>	*/
54 	"11111000000",		/* 018 - <DC2>	*/
55 	"11111010000",		/* 019 - <DC3>	*/
56 	"11111010100",		/* 020 - <DC4>	*/
57 	"11111011000",		/* 021 - <NAK>	*/
58 	"11111011100",		/* 022 - <SYN>	*/
59 	"11111100000",		/* 023 - <ETB>	*/
60 	"11111101000",		/* 024 - <CAN>	*/
61 	"11111101100",		/* 025 - <EM>	*/
62 	"11111110000",		/* 026 - <SUB>	*/
63 	"11111110100",		/* 027 - <ESC>	*/
64 	"11111111000",		/* 028 - <FS>	*/
65 	"11111111100",		/* 029 - <GS>	*/
66 	"100000000000",		/* 030 - <RS>	*/
67 	"101000000000",		/* 031 - <US>	*/
68 	"100",				/* 032 - <SPC>	*/
69 	"111000000",		/* 033 - !	*/
70 	"111111100",		/* 034 - '"'	*/
71 	"1011011000",		/* 035 - #	*/
72 	"1010101000",		/* 036 - $	*/
73 	"1010100000",		/* 037 - %	*/
74 	"1000000000",		/* 038 - &	*/
75 	"110111100",		/* 039 - '	*/
76 	"111110100",		/* 040 - (	*/
77 	"111110000",		/* 041 - )	*/
78 	"1010110100",		/* 042 - *	*/
79 	"111100000",		/* 043 - +	*/
80 	"10100000",			/* 044 - ,	*/
81 	"111011000",		/* 045 - -	*/
82 	"111010100",		/* 046 - .	*/
83 	"111101000",		/* 047 - /	*/
84 	"11100000",			/* 048 - 0	*/
85 	"11110000",			/* 049 - 1	*/
86 	"101000000",		/* 050 - 2	*/
87 	"101010100",		/* 051 - 3	*/
88 	"101110100",		/* 052 - 4	*/
89 	"101100000",		/* 053 - 5	*/
90 	"101101100",		/* 054 - 6	*/
91 	"110100000",		/* 055 - 7	*/
92 	"110000000",		/* 056 - 8	*/
93 	"110101100",		/* 057 - 9	*/
94 	"111101100",		/* 058 - :	*/
95 	"111111000",		/* 059 - ;	*/
96 	"1011000000",		/* 060 - <	*/
97 	"111011100",		/* 061 - =	*/
98 	"1010111100",		/* 062 - >	*/
99 	"111010000",		/* 063 - ?	*/
100 	"1010000000",		/* 064 - @	*/
101 	"10111100",			/* 065 - A	*/
102 	"100000000",		/* 066 - B	*/
103 	"11010100",			/* 067 - C	*/
104 	"11011100",			/* 068 - D	*/
105 	"10111000",			/* 069 - E	*/
106 	"11111000",			/* 070 - F	*/
107 	"101010000",		/* 071 - G	*/
108 	"101011000",		/* 072 - H	*/
109 	"11000000",			/* 073 - I	*/
110 	"110110100",		/* 074 - J	*/
111 	"101111100",		/* 075 - K	*/
112 	"11110100",			/* 076 - L	*/
113 	"11101000",			/* 077 - M	*/
114 	"11111100",			/* 078 - N	*/
115 	"11010000",			/* 079 - O	*/
116 	"11101100",			/* 080 - P	*/
117 	"110110000",		/* 081 - Q	*/
118 	"11011000",			/* 082 - R	*/
119 	"10110100",			/* 083 - S	*/
120 	"10110000",			/* 084 - T	*/
121 	"101011100",		/* 085 - U	*/
122 	"110101000",		/* 086 - V	*/
123 	"101101000",		/* 087 - W	*/
124 	"101110000",		/* 088 - X	*/
125 	"101111000",		/* 089 - Y	*/
126 	"110111000",		/* 090 - Z	*/
127 	"1011101000",		/* 091 - [	*/
128 	"1011010000",		/* 092 - \	*/
129 	"1011101100",		/* 093 - ]	*/
130 	"1011010100",		/* 094 - ^	*/
131 	"1010110000",		/* 095 - _	*/
132 	"1010101100",		/* 096 - `	*/
133 	"10100",			/* 097 - a	*/
134 	"1100000",			/* 098 - b	*/
135 	"111000",			/* 099 - c	*/
136 	"110100",			/* 100 - d	*/
137 	"1000",				/* 101 - e	*/
138 	"1010000",			/* 102 - f	*/
139 	"1011000",			/* 103 - g	*/
140 	"110000",			/* 104 - h	*/
141 	"11000",			/* 105 - i	*/
142 	"10000000",			/* 106 - j	*/
143 	"1110000",			/* 107 - k	*/
144 	"101100",			/* 108 - l	*/
145 	"1000000",			/* 109 - m	*/
146 	"11100",			/* 110 - n	*/
147 	"10000",			/* 111 - o	*/
148 	"1010100",			/* 112 - p	*/
149 	"1111000",			/* 113 - q	*/
150 	"100000",			/* 114 - r	*/
151 	"101000",			/* 115 - s	*/
152 	"1100",				/* 116 - t	*/
153 	"111100",			/* 117 - u	*/
154 	"1101100",			/* 118 - v	*/
155 	"1101000",			/* 119 - w	*/
156 	"1110100",			/* 120 - x	*/
157 	"1011100",			/* 121 - y	*/
158 	"1111100",			/* 122 - z	*/
159 	"1011011100",		/* 123 - {	*/
160 	"1010111000",		/* 124 - |	*/
161 	"1011100000",		/* 125 - }	*/
162 	"1011110000",		/* 126 - ~	*/
163 	"101010000000",		/* 127 - <DEL>	*/
164 	"101010100000",		/* 128 - 	*/
165 	"101010101000",		/* 129 - 	*/
166 	"101010101100",		/* 130 - 	*/
167 	"101010110000",		/* 131 - 	*/
168 	"101010110100",		/* 132 - 	*/
169 	"101010111000",		/* 133 - 	*/
170 	"101010111100",		/* 134 - 	*/
171 	"101011000000",		/* 135 - 	*/
172 	"101011010000",		/* 136 - 	*/
173 	"101011010100",		/* 137 - 	*/
174 	"101011011000",		/* 138 - 	*/
175 	"101011011100",		/* 139 - 	*/
176 	"101011100000",		/* 140 - 	*/
177 	"101011101000",		/* 141 - 	*/
178 	"101011101100",		/* 142 - 	*/
179 	"101011110000",		/* 143 - 	*/
180 	"101011110100",		/* 144 - 	*/
181 	"101011111000",		/* 145 - 	*/
182 	"101011111100",		/* 146 - 	*/
183 	"101100000000",		/* 147 - 	*/
184 	"101101000000",		/* 148 - 	*/
185 	"101101010000",		/* 149 - 	*/
186 	"101101010100",		/* 150 - 	*/
187 	"101101011000",		/* 151 - 	*/
188 	"101101011100",		/* 152 - 	*/
189 	"101101100000",		/* 153 - 	*/
190 	"101101101000",		/* 154 - 	*/
191 	"101101101100",		/* 155 - 	*/
192 	"101101110000",		/* 156 - 	*/
193 	"101101110100",		/* 157 - 	*/
194 	"101101111000",		/* 158 - 	*/
195 	"101101111100",		/* 159 - 	*/
196 	"1011110100",		/* 160 - 	*/
197 	"1011111000",		/* 161 - �	*/
198 	"1011111100",		/* 162 - �	*/
199 	"1100000000",		/* 163 - �	*/
200 	"1101000000",		/* 164 - �	*/
201 	"1101010000",		/* 165 - �	*/
202 	"1101010100",		/* 166 - �	*/
203 	"1101011000",		/* 167 - �	*/
204 	"1101011100",		/* 168 - �	*/
205 	"1101100000",		/* 169 - �	*/
206 	"1101101000",		/* 170 - �	*/
207 	"1101101100",		/* 171 - �	*/
208 	"1101110000",		/* 172 - �	*/
209 	"1101110100",		/* 173 - �	*/
210 	"1101111000",		/* 174 - �	*/
211 	"1101111100",		/* 175 - �	*/
212 	"1110000000",		/* 176 - �	*/
213 	"1110100000",		/* 177 - �	*/
214 	"1110101000",		/* 178 - �	*/
215 	"1110101100",		/* 179 - �	*/
216 	"1110110000",		/* 180 - �	*/
217 	"1110110100",		/* 181 - �	*/
218 	"1110111000",		/* 182 - �	*/
219 	"1110111100",		/* 183 - �	*/
220 	"1111000000",		/* 184 - �	*/
221 	"1111010000",		/* 185 - �	*/
222 	"1111010100",		/* 186 - �	*/
223 	"1111011000",		/* 187 - �	*/
224 	"1111011100",		/* 188 - �	*/
225 	"1111100000",		/* 189 - �	*/
226 	"1111101000",		/* 190 - �	*/
227 	"1111101100",		/* 191 - �	*/
228 	"1111110000",		/* 192 - �	*/
229 	"1111110100",		/* 193 - �	*/
230 	"1111111000",		/* 194 - �	*/
231 	"1111111100",		/* 195 - �	*/
232 	"10000000000",		/* 196 - �	*/
233 	"10100000000",		/* 197 - �	*/
234 	"10101000000",		/* 198 - �	*/
235 	"10101010000",		/* 199 - �	*/
236 	"10101010100",		/* 200 - �	*/
237 	"10101011000",		/* 201 - �	*/
238 	"10101011100",		/* 202 - �	*/
239 	"10101100000",		/* 203 - �	*/
240 	"10101101000",		/* 204 - �	*/
241 	"10101101100",		/* 205 - �	*/
242 	"10101110000",		/* 206 - �	*/
243 	"10101110100",		/* 207 - �	*/
244 	"10101111000",		/* 208 - �	*/
245 	"10101111100",		/* 209 - �	*/
246 	"10110000000",		/* 210 - �	*/
247 	"10110100000",		/* 211 - �	*/
248 	"10110101000",		/* 212 - �	*/
249 	"10110101100",		/* 213 - �	*/
250 	"10110110000",		/* 214 - �	*/
251 	"10110110100",		/* 215 - �	*/
252 	"10110111000",		/* 216 - �	*/
253 	"10110111100",		/* 217 - �	*/
254 	"10111000000",		/* 218 - �	*/
255 	"10111010000",		/* 219 - �	*/
256 	"10111010100",		/* 220 - �	*/
257 	"10111011000",		/* 221 - �	*/
258 	"10111011100",		/* 222 - �	*/
259 	"10111100000",		/* 223 - �	*/
260 	"10111101000",		/* 224 - �	*/
261 	"10111101100",		/* 225 - �	*/
262 	"10111110000",		/* 226 - �	*/
263 	"10111110100",		/* 227 - �	*/
264 	"10111111000",		/* 228 - �	*/
265 	"10111111100",		/* 229 - �	*/
266 	"11000000000",		/* 230 - �	*/
267 	"11010000000",		/* 231 - �	*/
268 	"11010100000",		/* 232 - �	*/
269 	"11010101000",		/* 233 - �	*/
270 	"11010101100",		/* 234 - �	*/
271 	"11010110000",		/* 235 - �	*/
272 	"11010110100",		/* 236 - �	*/
273 	"11010111000",		/* 237 - �	*/
274 	"11010111100",		/* 238 - �	*/
275 	"11011000000",		/* 239 - �	*/
276 	"11011010000",		/* 240 - �	*/
277 	"11011010100",		/* 241 - �	*/
278 	"11011011000",		/* 242 - �	*/
279 	"11011011100",		/* 243 - �	*/
280 	"11011100000",		/* 244 - �	*/
281 	"11011101000",		/* 245 - �	*/
282 	"11011101100",		/* 246 - �	*/
283 	"11011110000",		/* 247 - �	*/
284 	"11011110100",		/* 248 - �	*/
285 	"11011111000",		/* 249 - �	*/
286 	"11011111100",		/* 250 - �	*/
287 	"11100000000",		/* 251 - �	*/
288 	"11101000000",		/* 252 - n	*/
289 	"11101010000",		/* 253 - �	*/
290 	"11101010100",		/* 254 - �	*/
291 	"11101011000"		/* 255 - �	*/
292 };
293 
294 /*
295  * The same in a format more suitable for decoding.
296  */
297 static const unsigned int varidecode[] = {
298 	0x75C, 0x760, 0x768, 0x76C, 0x770, 0x774, 0x778, 0x77C,
299 	0x0A8, 0x780, 0x7A0, 0x7A8, 0x7AC, 0x0AC, 0x7B0, 0x7B4,
300 	0x7B8, 0x7BC, 0x7C0, 0x7D0, 0x7D4, 0x7D8, 0x7DC, 0x7E0,
301 	0x7E8, 0x7EC, 0x7F0, 0x7F4, 0x7F8, 0x7FC, 0x800, 0xA00,
302 	0x004, 0x1C0, 0x1FC, 0x2D8, 0x2A8, 0x2A0, 0x200, 0x1BC,
303 	0x1F4, 0x1F0, 0x2B4, 0x1E0, 0x0A0, 0x1D8, 0x1D4, 0x1E8,
304 	0x0E0, 0x0F0, 0x140, 0x154, 0x174, 0x160, 0x16C, 0x1A0,
305 	0x180, 0x1AC, 0x1EC, 0x1F8, 0x2C0, 0x1DC, 0x2BC, 0x1D0,
306 	0x280, 0x0BC, 0x100, 0x0D4, 0x0DC, 0x0B8, 0x0F8, 0x150,
307 	0x158, 0x0C0, 0x1B4, 0x17C, 0x0F4, 0x0E8, 0x0FC, 0x0D0,
308 	0x0EC, 0x1B0, 0x0D8, 0x0B4, 0x0B0, 0x15C, 0x1A8, 0x168,
309 	0x170, 0x178, 0x1B8, 0x2E8, 0x2D0, 0x2EC, 0x2D4, 0x2B0,
310 	0x2AC, 0x014, 0x060, 0x038, 0x034, 0x008, 0x050, 0x058,
311 	0x030, 0x018, 0x080, 0x070, 0x02C, 0x040, 0x01C, 0x010,
312 	0x054, 0x078, 0x020, 0x028, 0x00C, 0x03C, 0x06C, 0x068,
313 	0x074, 0x05C, 0x07C, 0x2DC, 0x2B8, 0x2E0, 0x2F0, 0xA80,
314 	0xAA0, 0xAA8, 0xAAC, 0xAB0, 0xAB4, 0xAB8, 0xABC, 0xAC0,
315 	0xAD0, 0xAD4, 0xAD8, 0xADC, 0xAE0, 0xAE8, 0xAEC, 0xAF0,
316 	0xAF4, 0xAF8, 0xAFC, 0xB00, 0xB40, 0xB50, 0xB54, 0xB58,
317 	0xB5C, 0xB60, 0xB68, 0xB6C, 0xB70, 0xB74, 0xB78, 0xB7C,
318 	0x2F4, 0x2F8, 0x2FC, 0x300, 0x340, 0x350, 0x354, 0x358,
319 	0x35C, 0x360, 0x368, 0x36C, 0x370, 0x374, 0x378, 0x37C,
320 	0x380, 0x3A0, 0x3A8, 0x3AC, 0x3B0, 0x3B4, 0x3B8, 0x3BC,
321 	0x3C0, 0x3D0, 0x3D4, 0x3D8, 0x3DC, 0x3E0, 0x3E8, 0x3EC,
322 	0x3F0, 0x3F4, 0x3F8, 0x3FC, 0x400, 0x500, 0x540, 0x550,
323 	0x554, 0x558, 0x55C, 0x560, 0x568, 0x56C, 0x570, 0x574,
324 	0x578, 0x57C, 0x580, 0x5A0, 0x5A8, 0x5AC, 0x5B0, 0x5B4,
325 	0x5B8, 0x5BC, 0x5C0, 0x5D0, 0x5D4, 0x5D8, 0x5DC, 0x5E0,
326 	0x5E8, 0x5EC, 0x5F0, 0x5F4, 0x5F8, 0x5FC, 0x600, 0x680,
327 	0x6A0, 0x6A8, 0x6AC, 0x6B0, 0x6B4, 0x6B8, 0x6BC, 0x6C0,
328 	0x6D0, 0x6D4, 0x6D8, 0x6DC, 0x6E0, 0x6E8, 0x6EC, 0x6F0,
329 	0x6F4, 0x6F8, 0x6FC, 0x700, 0x740, 0x750, 0x754, 0x758
330 };
331 
varienc(int c)332 const char *varienc(int c)
333 {
334 	if (c >= 0 && c < 256)
335 		return varicode[c];
336 	return varicode[0];
337 }
338 
varidec(unsigned int symbol)339 int varidec(unsigned int symbol)
340 {
341 	int i;
342 
343 	for (i = 0; i < 256; i++)
344 		if (symbol == varidecode[i])
345 			return i;
346 
347 	return -1;
348 }
349 
350