1 /*
2 * Tlf - contest logging program for amateur radio operators
3 * Copyright (C) 2013 Thomas Beierlein <tb@forth-ev.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <glib.h>
25
26 #define CW_SPEEDS "06121416182022242628303234363840424446485060"
27 /*< speed string with 2 chars each (in WPM) */
28
29
30 char speedstr[50] = CW_SPEEDS;
31 int speed = 10;
32
33
34 /* converts cw speed in wpm to an numbered index into speedstr table */
speed_conversion(int cwspeed)35 int speed_conversion(int cwspeed) {
36
37 int x;
38
39 switch (cwspeed) {
40
41 case 0 ... 6: {
42 x = 0;
43 break;
44 }
45 case 7 ... 12: {
46 x = 1;
47 break;
48 }
49 case 13 ... 14: {
50 x = 2;
51 break;
52 }
53 case 15 ... 16: {
54 x = 3;
55 break;
56 }
57 case 17 ... 18: {
58 x = 4;
59 break;
60 }
61 case 19 ... 20: {
62 x = 5;
63 break;
64 }
65 case 21 ... 22: {
66 x = 6;
67 break;
68 }
69 case 23 ... 24: {
70 x = 7;
71 break;
72 }
73 case 25 ... 26: {
74 x = 8;
75 break;
76 }
77 case 27 ... 28: {
78 x = 9;
79 break;
80 }
81 case 29 ... 30: {
82 x = 10;
83 break;
84 }
85 case 31 ... 32: {
86 x = 11;
87 break;
88 }
89 case 33 ... 34: {
90 x = 12;
91 break;
92 }
93 case 35 ... 36: {
94 x = 13;
95 break;
96 }
97 case 37 ... 38: {
98 x = 14;
99 break;
100 }
101 case 39 ... 40: {
102 x = 15;
103 break;
104 }
105 case 41 ... 42: {
106 x = 16;
107 break;
108 }
109 case 43 ... 44: {
110 x = 17;
111 break;
112 }
113 case 45 ... 46: {
114 x = 18;
115 break;
116 }
117 case 47 ... 48: {
118 x = 19;
119 break;
120 }
121 default: {
122 x = 20;
123 break;
124 }
125 }
126
127 return (x);
128 }
129
130
131 /** Set CW speed
132 *
133 * Set CW speed to the nearest supported value. Converts it into an index into
134 * the speed table and stores that.
135 * \param wpm The CW speed in WPM
136 */
SetCWSpeed(unsigned int wpm)137 void SetCWSpeed(unsigned int wpm) {
138 speed = speed_conversion(wpm);
139 }
140
141
142 /* Get CW speed
143 *
144 * Return the actual CW speed in WPM as integer
145 * \return The CW speed in WPM
146 */
GetCWSpeed()147 unsigned int GetCWSpeed() {
148 char buff[3];
149
150 g_strlcpy(buff, speedstr + (2 * speed), 3);
151 return (atoi(buff));
152 }
153
154
155 /** get length of CW characters
156 *
157 * converts a given CW character into the number of dot elements
158 * \param ch the character to convert
159 * \return number of dots for the character including the following character
160 * space
161 */
getCWdots(char ch)162 unsigned int getCWdots(char ch) {
163
164 unsigned int length;
165
166 switch (ch) {
167 case 'A':
168 length = 9;
169 break;
170 case 'B':
171 length = 13;
172 break;
173 case 'C':
174 length = 15;
175 break;
176 case 'D':
177 length = 11;
178 break;
179 case 'E':
180 length = 5;
181 break;
182 case 'F':
183 length = 13;
184 break;
185 case 'G':
186 length = 13;
187 break;
188 case 'H':
189 length = 11;
190 break;
191 case 'I':
192 length = 7;
193 break;
194 case 'J':
195 length = 17;
196 break;
197 case 'K':
198 length = 13;
199 break;
200 case 'L':
201 length = 13;
202 break;
203 case 'M':
204 length = 11;
205 break;
206 case 'N':
207 length = 9;
208 break;
209 case 'O':
210 length = 15;
211 break;
212 case 'P':
213 length = 15;
214 break;
215 case 'Q':
216 length = 17;
217 break;
218 case 'R':
219 length = 11;
220 break;
221 case 'S':
222 length = 9;
223 break;
224 case 'T':
225 length = 7;
226 break;
227 case 'U':
228 length = 11;
229 break;
230 case 'V':
231 length = 13;
232 break;
233 case 'W':
234 length = 13;
235 break;
236 case 'X':
237 length = 15;
238 break;
239 case 'Y':
240 length = 17;
241 break;
242 case 'Z':
243 length = 15;
244 break;
245 case '0':
246 length = 23;
247 break;
248 case '1':
249 length = 21;
250 break;
251 case '2':
252 length = 19;
253 break;
254 case '3':
255 length = 17;
256 break;
257 case '4':
258 length = 15;
259 break;
260 case '5':
261 length = 13;
262 break;
263 case '6':
264 length = 15;
265 break;
266 case '7':
267 length = 17;
268 break;
269 case '8':
270 length = 19;
271 break;
272 case '9':
273 length = 21;
274 break;
275 case '/':
276 length = 17;
277 break;
278 case '?':
279 length = 19;
280 break;
281 case ' ':
282 length = 3;
283 break;
284 default:
285 length = 0;
286 }
287 return (length);
288 }
289
290
291 /** calculate dot length of a cw message
292 *
293 * Calculate the length of a given CW message in dot elements.
294 * Expands '%' into your own call.
295 * \param message the CW message
296 * \return number of dot elements in the message
297 */
cw_message_length(char * message)298 unsigned int cw_message_length(char *message) {
299
300 extern char call[];
301
302 int i;
303 int message_length = 0;
304 char cwmessage[80];
305 int testchar, j;
306
307 strncpy(cwmessage, message, 79);
308 cwmessage[79] = '\0';
309
310 for (i = 0; i < strlen(cwmessage); i++) {
311
312 testchar = cwmessage[i];
313 if (testchar == '%') {
314 for (j = 0; j < strlen(call); j++) {
315 testchar = call[j];
316 message_length += getCWdots(testchar);
317 }
318
319 } else
320 message_length += getCWdots(testchar);
321
322 }
323 return (message_length);
324 }
325
326