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