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