1 /*
2  * Copyright (C) 2001-2006  Simon Baldwin (simon_baldwin@yahoo.com)
3  * Copyright (C) 2011-2017  Kamil Ignacak (acerion@wp.pl)
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (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 along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef _LIBCW_H
21 #define _LIBCW_H
22 
23 #include <sys/time.h>  /* For struct timeval */
24 
25 #include <stdint.h>    /* int16_t */
26 #include <pthread.h>
27 #include <stdbool.h>
28 
29 
30 static const int        CW_AUDIO_CHANNELS = 1;                /* Sound in mono */
31 
32 
33 #if defined(__cplusplus)
34 extern "C"
35 {
36 #endif
37 
38 
39 enum cw_return_values {
40 	CW_FAILURE = false,
41 	CW_SUCCESS = true };
42 
43 /* supported audio sound systems */
44 enum cw_audio_systems {
45 	CW_AUDIO_NONE = 0,  /* initial value; this is not the same as CW_AUDIO_NULL */
46 	CW_AUDIO_NULL,      /* empty audio output (no sound, just timing); this is not the same as CW_AUDIO_NONE */
47 	CW_AUDIO_CONSOLE,   /* console buzzer */
48 	CW_AUDIO_OSS,
49 	CW_AUDIO_ALSA,
50 	CW_AUDIO_PA,        /* PulseAudio */
51 	CW_AUDIO_SOUNDCARD  /* OSS, ALSA or PulseAudio (PA) */
52 };
53 
54 enum {
55 	CW_KEY_STATE_OPEN = 0,  /* key is open, no electrical contact in key, no sound */
56 	CW_KEY_STATE_CLOSED     /* key is closed, there is an electrical contact in key, a sound is generated */
57 };
58 
59 
60 typedef int16_t cw_sample_t;
61 
62 
63 
64 /* Default outputs for audio systems. Used by libcw unless
65    client code decides otherwise. */
66 #define CW_DEFAULT_NULL_DEVICE      ""
67 #define CW_DEFAULT_CONSOLE_DEVICE   "/dev/console"
68 #define CW_DEFAULT_OSS_DEVICE       "/dev/audio"
69 #define CW_DEFAULT_ALSA_DEVICE      "default"
70 #define CW_DEFAULT_PA_DEVICE        "( default )"
71 
72 
73 /* Limits on values of CW send and timing parameters */
74 #define CW_SPEED_MIN             4   /* Lowest WPM allowed */
75 #define CW_SPEED_MAX            60   /* Highest WPM allowed */
76 #define CW_SPEED_STEP            1
77 #define CW_SPEED_INITIAL        12   /* Initial send speed in WPM */
78 #define CW_FREQUENCY_MIN         0   /* Lowest tone allowed (0=silent) */
79 #define CW_FREQUENCY_MAX      4000   /* Highest tone allowed */
80 #define CW_FREQUENCY_INITIAL   800   /* Initial tone in Hz */
81 #define CW_FREQUENCY_STEP       20
82 #define CW_VOLUME_MIN            0   /* Quietest volume allowed (0=silent) */
83 #define CW_VOLUME_MAX          100   /* Loudest volume allowed */
84 #define CW_VOLUME_INITIAL       70   /* Initial volume percent */
85 #define CW_VOLUME_STEP           1
86 #define CW_GAP_MIN               0   /* Lowest extra gap allowed */
87 #define CW_GAP_MAX              60   /* Highest extra gap allowed */
88 #define CW_GAP_INITIAL           0   /* Initial gap setting */
89 #define CW_GAP_STEP              1
90 #define CW_WEIGHTING_MIN        20   /* Lowest weighting allowed */
91 #define CW_WEIGHTING_MAX        80   /* Highest weighting allowed */
92 #define CW_WEIGHTING_INITIAL    50   /* Initial weighting setting */
93 #define CW_TOLERANCE_MIN         0   /* Lowest receive tolerance allowed */
94 #define CW_TOLERANCE_MAX        90   /* Highest receive tolerance allowed */
95 #define CW_TOLERANCE_INITIAL    50   /* Initial tolerance setting */
96 
97 
98 /*
99  * Representation characters for Dot and Dash.  Only the following
100  * characters are permitted in Morse representation strings.
101  */
102 enum { CW_DOT_REPRESENTATION = '.', CW_DASH_REPRESENTATION = '-' };
103 
104 
105 
106 /* Debugging support. */
107 
108 /* Definitions of debug flags. */
109 enum {
110 	/* Suppress KIOCSOUND ioctls.
111 	   The flag is unused at the moment in libcw.c. */
112 	CW_DEBUG_SILENT               = 1 << 0,
113 
114 	/* Print out keying control data (key open / key closed). */
115 	CW_DEBUG_KEYING               = 1 << 1,
116 
117 	/* Print out information related to main object generating
118 	   audio (i.e. the generator). */
119 	CW_DEBUG_GENERATOR            = 1 << 2,
120 
121 	/* Print out tone queue data. */
122 	CW_DEBUG_TONE_QUEUE           = 1 << 3,
123 
124 	/* Print out send and receive timing parameters. */
125 	CW_DEBUG_PARAMETERS           = 1 << 4,
126 
127 	/* Print out changes of 'receive state'. */
128 	CW_DEBUG_RECEIVE_STATES       = 1 << 5,
129 
130 	/* Print out iambic keyer information. */
131 	CW_DEBUG_KEYER_STATES         = 1 << 6,
132 
133 	/* Print out straight key information. */
134 	CW_DEBUG_STRAIGHT_KEY_STATES  = 1 << 7,
135 
136 	/* Print out table lookup results. */
137 	CW_DEBUG_LOOKUPS              = 1 << 8,
138 
139 	/* Print out finalization actions. */
140 	CW_DEBUG_FINALIZATION         = 1 << 9,
141 
142 	/* Print out information related to calls to standard library
143 	   functions.  This does not include calls that are directly
144 	   related to configuring audio devices (e.g. calling open()
145 	   to open OSS device).
146 
147 	   Printing debug information about problems with malloc()
148 	   seems to be most common use case for this flag. */
149 	CW_DEBUG_STDLIB               = 1 << 10,
150 
151 	/* Print out any events directly related to sound systems: to
152 	   opening audio device, configuring it, writing to it, and
153 	   closing it.  In case of e.g. OSS sound system, this may
154 	   also include information about libc's open(), write() and
155 	   ioctl() calls, as they are directly related to
156 	   opening/configuring/writing to audio device. */
157 	CW_DEBUG_SOUND_SYSTEM         = 1 << 11,
158 
159 	/* Print out information related to internal states / errors /
160 	   inconsistencies of libcw library. */
161 	CW_DEBUG_INTERNAL             = 1 << 12,
162 
163 	/* Bit mask of all defined debug bits. */
164 	CW_DEBUG_MASK                 = (1 << 13) - 1
165 };
166 
167 
168 
169 /* Debug levels of debug messages. */
170 enum {
171 	CW_DEBUG_DEBUG   = 0,
172 	CW_DEBUG_INFO    = 1,
173 	CW_DEBUG_WARNING = 2,
174 	CW_DEBUG_ERROR   = 3,
175 	CW_DEBUG_NONE    = 4  /* Don't print any debug info. */
176 };
177 
178 
179 
180 
181 /* Values deciding the shape of slopes of tones generated by
182    generator.
183 
184    If a generated tone is declared to have one or two slopes,
185    generator has to know what shape of the slope(s) should be. Since
186    the shape of tones is common for all tones generated by generator,
187    shape of tone is a property of generator rather than of tone.
188 
189    These names are to be used as values of argument 'slope_shape' of
190    cw_generator_set_tone_slope() function.  */
191 enum {
192 	CW_TONE_SLOPE_SHAPE_LINEAR,          /* Ramp/linearly raising slope. */
193 	CW_TONE_SLOPE_SHAPE_RAISED_COSINE,   /* Shape of cosine function in range <-pi - zero).  */
194 	CW_TONE_SLOPE_SHAPE_SINE,            /* Shape of sine function in range <zero - pi/2). */
195 	CW_TONE_SLOPE_SHAPE_RECTANGULAR      /* Slope changes from zero for sample n, to full amplitude of tone in sample n+1. */
196 };
197 
198 typedef struct cw_gen_struct cw_gen_t;
199 
200 
201 /* Functions handling library meta data */
202 extern int  cw_version(void);
203 extern void cw_license(void);
204 extern const char *cw_get_audio_system_label(int audio_system);
205 
206 
207 
208 /* Functions handling 'generator' */
209 extern int  cw_generator_new(int audio_system, const char *device);
210 extern void cw_generator_delete(void);
211 extern int  cw_generator_start(void);
212 extern void cw_generator_stop(void);
213 extern const char *cw_generator_get_audio_system_label(void);
214 /* FIXME: first argument of the function is gen, but no function provides access to generator variable. */
215 extern int  cw_generator_set_tone_slope(cw_gen_t *gen, int slope_shape, int slope_usecs);
216 
217 /* Core Morse code data and lookup */
218 extern int   cw_get_character_count(void);
219 extern void  cw_list_characters(char *list);
220 extern int   cw_get_maximum_representation_length(void);
221 extern char *cw_character_to_representation(int c);
222 extern bool  cw_representation_is_valid(const char *representation);
223 extern int   cw_representation_to_character(const char *representation);
224 
225 
226 /* Extended Morse code data and lookup (procedural signals) */
227 extern int cw_get_procedural_character_count(void);
228 extern void cw_list_procedural_characters(char *list);
229 extern int cw_get_maximum_procedural_expansion_length(void);
230 
231 extern int cw_lookup_procedural_character (char c, char *representation,
232                                            int *is_usually_expanded);
233 
234 
235 /* Phonetic alphabet */
236 extern int cw_get_maximum_phonetic_length(void);
237 extern int cw_lookup_phonetic(char c, char *phonetic);
238 
239 
240 /* Morse code controls and timing parameters */
241 extern void cw_get_speed_limits(int *min_speed, int *max_speed);
242 extern void cw_get_frequency_limits(int *min_frequency, int *max_frequency);
243 extern void cw_get_volume_limits(int *min_volume, int *max_volume);
244 extern void cw_get_gap_limits(int *min_gap, int *max_gap);
245 extern void cw_get_tolerance_limits(int *min_tolerance, int *max_tolerance);
246 extern void cw_get_weighting_limits(int *min_weighting, int *max_weighting);
247 extern void cw_reset_send_receive_parameters(void);
248 extern int cw_set_send_speed(int new_value);
249 extern int cw_set_receive_speed(int new_value);
250 extern int cw_set_frequency(int new_value);
251 extern int cw_set_volume(int new_value);
252 extern int cw_set_gap(int new_value);
253 extern int cw_set_tolerance(int new_value);
254 extern int cw_set_weighting(int new_value);
255 extern int cw_get_send_speed(void);
256 extern int cw_get_receive_speed(void);
257 extern int cw_get_frequency(void);
258 extern int cw_get_volume(void);
259 extern int cw_get_gap(void);
260 extern int cw_get_tolerance(void);
261 extern int cw_get_weighting(void);
262 extern void cw_get_send_parameters(int *dot_usecs, int *dash_usecs,
263 				   int *end_of_element_usecs,
264 				   int *end_of_character_usecs,
265 				   int *end_of_word_usecs,
266 				   int *additional_usecs,
267 				   int *adjustment_usecs);
268 extern void cw_get_receive_parameters(int *dot_usecs, int *dash_usecs,
269 				      int *dot_min_usecs, int *dot_max_usecs,
270 				      int *dash_min_usecs, int *dash_max_usecs,
271 				      int *end_of_element_min_usecs,
272 				      int *end_of_element_max_usecs,
273 				      int *end_of_element_ideal_usecs,
274 				      int *end_of_character_min_usecs,
275 				      int *end_of_character_max_usecs,
276 				      int *end_of_character_ideal_usecs,
277 				      int *adaptive_threshold);
278 extern int cw_set_noise_spike_threshold(int new_value);
279 extern int cw_get_noise_spike_threshold(void);
280 
281 
282 extern void cw_block_callback(int block);
283 
284 
285 /* General control of console buzzer and of soundcard */
286 extern const char *cw_get_console_device(void);
287 extern const char *cw_get_soundcard_device(void);
288 
289 
290 extern bool cw_is_null_possible(const char *device);
291 extern bool cw_is_console_possible(const char *device);
292 extern bool cw_is_oss_possible(const char *device);
293 extern bool cw_is_alsa_possible(const char *device);
294 extern bool cw_is_pa_possible(const char *device);
295 
296 
297 
298 
299 /* Finalization and cleanup */
300 extern void cw_complete_reset(void);
301 extern int  cw_register_signal_handler(int signal_number,
302 				       void (*callback_func)(int));
303 extern int  cw_unregister_signal_handler(int signal_number);
304 
305 
306 
307 
308 /* Keying control */
309 extern void cw_register_keying_callback(void (*callback_func)(void*, int),
310 					void *callback_arg);
311 extern void cw_iambic_keyer_register_timer(struct timeval *timer);
312 
313 
314 /* Tone queue */
315 extern int cw_register_tone_queue_low_callback(void (*callback_func) (void*),
316                                                 void *callback_arg, int level);
317 extern bool cw_is_tone_busy(void);
318 extern int  cw_wait_for_tone(void);
319 extern int  cw_wait_for_tone_queue(void);
320 extern int  cw_wait_for_tone_queue_critical(int level);
321 extern bool cw_is_tone_queue_full(void);
322 extern int  cw_get_tone_queue_capacity(void);
323 extern int  cw_get_tone_queue_length(void);
324 extern void cw_flush_tone_queue(void);
325 extern int  cw_queue_tone(int usecs, int frequency);
326 extern void cw_reset_tone_queue(void);
327 
328 
329 
330 /* Sending */
331 extern int cw_send_dot(void);
332 extern int cw_send_dash(void);
333 extern int cw_send_character_space(void);
334 extern int cw_send_word_space(void);
335 extern int cw_send_representation(const char *representation);
336 extern int cw_send_representation_partial(const char *representation);
337 extern int cw_send_character(char c);
338 extern int cw_send_character_partial(char c);
339 extern int cw_send_string(const char *string);
340 
341 extern bool cw_character_is_valid(char c);
342 extern bool cw_string_is_valid(const char *string);
343 
344 
345 
346 /* Receive tracking and statistics helpers */
347 extern void cw_get_receive_statistics(double *dot_sd, double *dash_sd,
348                                        double *element_end_sd,
349                                        double *character_end_sd);
350 extern void cw_reset_receive_statistics(void);
351 
352 
353 /* Receiving */
354 extern void cw_enable_adaptive_receive(void);
355 extern void cw_disable_adaptive_receive(void);
356 extern bool cw_get_adaptive_receive_state(void);
357 extern int cw_start_receive_tone(const struct timeval *timestamp);
358 extern int cw_end_receive_tone(const struct timeval *timestamp);
359 
360 /* If I'm reading xcwcp/receiver.cc correctly then currently libcw
361    implements polling interface to receiver code. Client code must
362    periodically poll libcw to see if there is a new character or space
363    in receiver's representation buffer. These four functions below are
364    the main part of "polling".
365 
366    TODO: implement alternative way of accessing receiver's
367    representation buffer (or maybe sharing the buffer's content by
368    receiver). Some kind of scheme where receiver informs client code
369    about the fact that the receiver ended receiving marks/spaces and
370    recognized full character or space. Some kind of notification to
371    the client code, or calling client's callback function. */
372 extern int cw_receive_buffer_dot(const struct timeval *timestamp);
373 extern int cw_receive_buffer_dash(const struct timeval *timestamp);
374 extern int cw_receive_representation(const struct timeval *timestamp,
375 				     char *representation,
376 				     bool *is_end_of_word, bool *is_error);
377 extern int cw_receive_character(const struct timeval *timestamp,
378                                  char *c, bool *is_end_of_word, bool *is_error);
379 /* It seems that this function is a part of the polling interface as
380    well. It is called by client code in xcwcp/receiver.cc after
381    passing recognized character from receiver to client code. It makes
382    space in the receiver's buffer for next character. */
383 extern void cw_clear_receive_buffer(void);
384 
385 extern int cw_get_receive_buffer_capacity(void);
386 extern int cw_get_receive_buffer_length(void);
387 extern void cw_reset_receive(void);
388 
389 
390 /* Iambic keyer */
391 extern void cw_enable_iambic_curtis_mode_b(void);
392 extern void cw_disable_iambic_curtis_mode_b(void);
393 extern int cw_get_iambic_curtis_mode_b_state(void);
394 
395 extern int cw_notify_keyer_paddle_event(int dot_paddle_state,
396 					int dash_paddle_state);
397 extern int cw_notify_keyer_dot_paddle_event(int dot_paddle_state);
398 extern int cw_notify_keyer_dash_paddle_event(int dash_paddle_state);
399 extern void cw_get_keyer_paddles(int *dot_paddle_state,
400 				 int *dash_paddle_state);
401 extern void cw_get_keyer_paddle_latches(int *dot_paddle_latch_state,
402 					int *dash_paddle_latch_state);
403 extern bool cw_is_keyer_busy(void);
404 extern int cw_wait_for_keyer_element(void);
405 extern int cw_wait_for_keyer(void);
406 extern void cw_reset_keyer(void);
407 
408 
409 /* Straight key */
410 extern int cw_notify_straight_key_event(int key_state);
411 extern int cw_get_straight_key_state(void);
412 extern bool cw_is_straight_key_busy(void);
413 extern void cw_reset_straight_key(void);
414 
415 
416 
417 
418 /* deprecated functions */
419 extern int cw_check_representation(const char *representation)           __attribute__ ((deprecated));   /* Use cw_representation_is_valid(). */
420 extern int cw_lookup_representation(const char *representation, char *c) __attribute__ ((deprecated));   /* Use cw_representation_to_character(). */
421 extern int cw_lookup_character(char c, char *representation)             __attribute__ ((deprecated));   /* Use cw_character_to_representation(). */
422 extern int cw_check_character(char c)                                    __attribute__ ((deprecated));   /* Use cw_character_is_valid(). */
423 extern int cw_check_string(const char *string)                           __attribute__ ((deprecated));   /* Use cw_string_is_valid(). */
424 
425 
426 #if defined(__cplusplus)
427 }
428 #endif
429 #endif  /* _LIBCW_H */
430