SYNOPSIS

#include <libcw.h>

int cw_version(void)

void cw_license(void)

const char *cw_get_audio_system_label(int audio_system)

int cw_get_character_count(void)

void cw_list_characters(char *list)

int cw_get_maximum_representation_length(void)

int cw_lookup_character(char c, char *representation)

char *cw_character_to_representation(int c)

int cw_check_representation(const char *representation)

bool cw_representation_is_valid(const char *representation)

int cw_lookup_representation(const char *representation, char *c)

int cw_representation_to_character(const char *representation)

int cw_get_procedural_character_count(void)

void cw_list_procedural_characters(char *list)

int cw_get_maximum_procedural_expansion_length(void)

int cw_lookup_procedural_character(char c, char *expansion, int *is_usually_expanded)

int cw_get_maximum_phonetic_length(void)

int cw_lookup_phonetic(char c, char *phonetic)

void cw_get_speed_limits(int *min_speed, int *max_speed)

void cw_get_frequency_limits(int *min_frequency, int *max_frequency)

void cw_get_volume_limits(int *min_volume, int *max_volume)

void cw_get_gap_limits(int *min_gap, int *max_gap)

void cw_get_tolerance_limits(int *min_tolerance, int *max_tolerance)

void cw_get_weighting_limits(int *min_weighting, int *max_weighting)

void cw_reset_send_receive_parameters(void)

int cw_set_send_speed(int new_value)

int cw_set_receive_speed(int new_value)

int cw_set_frequency(int new_value)

int cw_set_volume(int new_value)

int cw_set_gap(int new_value)

int cw_set_tolerance(int new_value)

int cw_set_weighting(int new_value)

int cw_get_send_speed(void)

int cw_get_receive_speed(void)

int cw_get_frequency(void)

int cw_get_volume(void)

int cw_get_gap(void)

int cw_get_tolerance(void)

int cw_get_weighting(void)

void cw_get_send_parameters(int *dot_usecs, int *dash_usecs,

int *end_of_element_usecs,

int *end_of_character_usecs, int *end_of_word_usecs,

int *additional_usecs, int *adjustment_usecs)

void cw_get_receive_parameters(int *dot_usecs, int *dash_usecs,

int *dot_min_usecs, int *dot_max_usecs,

int *dash_min_usecs, int *dash_max_usecs,

int *end_of_element_min_usecs,

int *end_of_element_max_usecs,

int *end_of_element_ideal_usecs,

int *end_of_character_min_usecs,

int *end_of_character_max_usecs,

int *end_of_character_ideal_usecs,

int *adaptive_threshold)

int cw_set_noise_spike_threshold(int new_value)

int cw_get_noise_spike_threshold(void)

void cw_block_callback(int block)

int cw_register_signal_handler(int signal_number, void (*callback_func)(int))

int cw_unregister_signal_handler(int signal_number)

const char *cw_get_console_device(void)

const char *cw_get_soundcard_device(void)

void cw_complete_reset(void)

void cw_register_keying_callback(void (*callback_func)(void*, int),

void *callback_arg)

int cw_register_tone_queue_low_callback(void (*callback_func)(void*), void *callback_arg, int level)

bool cw_is_tone_busy(void)

int cw_wait_for_tone(void)

int cw_wait_for_tone_queue(void)

int cw_wait_for_tone_queue_critical(int level)

bool cw_is_tone_queue_full(void)

int cw_get_tone_queue_capacity(void)

int cw_get_tone_queue_length(void)

void cw_flush_tone_queue(void)

int cw_queue_tone(int usecs, int frequency)

void cw_reset_tone_queue(void)

int cw_send_dot(void)

int cw_send_dash(void)

int cw_send_character_space(void)

int cw_send_word_space(void)

int cw_send_representation(const char *representation)

int cw_send_representation_partial(const char *representation)

bool cw_character_is_valid(char c)

int cw_send_character(char c)

int cw_send_character_partial(char c)

bool cw_string_is_valid(const char *string)

int cw_send_string(const char *string)

void cw_get_receive_statistics(double *dot_sd, double *dash_sd,

double *element_end_sd, double *character_end_sd)

void cw_reset_receive_statistics(void)

void cw_enable_adaptive_receive(void)

void cw_disable_adaptive_receive(void)

bool cw_get_adaptive_receive_state(void)

int cw_start_receive_tone(const struct timeval *timestamp)

int cw_end_receive_tone(const struct timeval *timestamp)

int cw_receive_buffer_dot(const struct timeval *timestamp)

int cw_receive_buffer_dash(const struct timeval *timestamp)

int cw_receive_representation(const struct timeval *timestamp,

/* out */ char *representation,

/* out */ bool *is_end_of_word, /* out */ bool *is_error)

int cw_receive_character(const struct timeval *timestamp,

/* out */ char *c,

/* out */ bool *is_end_of_word, /* out */ bool *is_error)

void cw_clear_receive_buffer(void)

int cw_get_receive_buffer_capacity(void)

int cw_get_receive_buffer_length(void)

void cw_reset_receive(void)

void cw_enable_iambic_curtis_mode_b(void)

void cw_disable_iambic_curtis_mode_b(void)

int cw_get_iambic_curtis_mode_b_state(void)

int cw_notify_keyer_paddle_event(int dot_paddle_state,

int dash_paddle_state)

int cw_notify_keyer_dot_paddle_event(int dot_paddle_state)

int cw_notify_keyer_dash_paddle_event(int dash_paddle_state)

void cw_get_keyer_paddles(int *dot_paddle_state, int *dash_paddle_state)

void cw_get_keyer_paddle_latches(int *dot_paddle_latch_state,

int *dash_paddle_latch_state)

bool cw_is_keyer_busy(void)

int cw_wait_for_keyer_element(void)

int cw_wait_for_keyer(void)

void cw_reset_keyer(void)

int cw_notify_straight_key_event(int key_state)

int cw_get_straight_key_state(void)

bool cw_is_straight_key_busy(void)

void cw_reset_straight_key(void)

const char *cw_generator_get_audio_system_label(void)

int cw_generator_new(int audio_system, const char *device)

void cw_generator_delete(void)

int cw_generator_start(void)

void cw_generator_stop(void)

int cw_generator_set_tone_slope(cw_gen_t *gen, int slope_shape, int slope_usecs)

unsigned int test_cw_tone_queue_test_capacity1(void)

unsigned int test_cw_tone_queue_test_capacity2(void)

int test_cw_tone_queue_capacity_test_init(cw_tone_queue_t *tq, uint32_t capacity, uint32_t high_water_mark, int head_shift)

DESCRIPTION

libcw is a general purpose CW (Morse code) functions library. It contains routines for converting characters into Morse code representations and back again, for sending Morse code characters, and for receiving characters. It also contains routines to emulate an Iambic Morse keyer, and a straight key.

The library can be included in any program that wishes to make use of these features. It forms the heart of three Morse code tutor applications that accompany the package in which it is distributed.

See the cw(7) man page for information on Morse code timings, and the dot and dash representations for the various Morse characters.

TONE QUEUE

libcw contains an inbuilt tone queue. The queue is emptied by background processing, using SIGALRM calls and itimers, so a caller program can continue with other tasks while the library sends tones and keys any external device.

As well as being used by the library functions that sound Morse code characters and provide a keyer sidetone, the primitive tone queue functions are publicly available to caller programs.

CONTROLLING AN EXTERNAL DEVICE

libcw may be passed the address of a function that controls external keying. This function is called each time the library changes the keying state, either as a result of sending a Morse character or representation, or as a result of an iambic keyer or straight key state change. The argument passed is a single integer, TRUE for key-down, and FALSE for key-up.

libcw calls the external keying function only when the keying state changes. A call is likely each time a tone is taken off the tone queue.

SENDING CW CHARACTERS AND STRINGS

libcw offers several functions that send individual characters and character strings as Morse code. It also offers functions that allow specialized 'representations' to be sent. A 'representation' is an ASCII string that consists of only the characters '.' and '-'.

Characters and strings are converted into representations, and then the correct tones for the dots and dashes in these representations are queued on the tone queue, for action by the background queue emptying process.

RECEIVING CW CHARACTERS AND REPRESENTATIONS

libcw contains functions to allow it to receive Morse code. To receive, the library must be told when a tone start is detected, and when a tone end is detected. It then determines whether the tone was a dot or a dash depending on the timing difference between the two. After the required silence gap has passed, the library may be queried to see what the received representation or character was.

Errors in receiving may be detected by means of the flags passed back on receive character functions.

IAMBIC KEYER

libcw offers functions to simulate an Iambic Morse keyer. The caller program needs to tell the library of paddle state changes. Iambic keyer functions are mutually exclusive with character send and straight key functions.

STRAIGHT KEY

libcw offers simple functions to allow effective pass-through of straight key information. The caller program needs to tell the library of key state changes. Straight key functions are mutually exclusive with character send and iambic keyer functions.

RETURN CODES

Some of the library's function return a return code of type int. The return code has two values, as defined in libcw.h: CW_SUCCESS or CW_FAILURE. The two symbolic constants are guaranteed to be identical to boolean true and false.

FUNCTIONS

The following list describes the functions available to a libcw caller:

int cw_version(void)

Brief: Return version number of libcw library

Return the version number of the library. Version numbers (major and minor) are returned as an int, composed of major_version << 16 | minor_version.

testedin::test_cw_version()

Returns: library's major and minor version number encoded as single int

void cw_license(void)

Brief: Print libcw's license text to stdout

testedin::test_cw_license()

Function prints information about libcw version, followed by short text presenting libcw's copyright and license notice.

const char *cw_get_audio_system_label(int audio_system)

Brief: Get a readable label of given audio system

The function returns one of following strings: None, Null, Console, OSS, ALSA, PulseAudio, Soundcard

Returned pointer is owned and managed by the library.

TODO: change the declaration to "const char *const cw_get_audio_system_label(...)"?

Parameter: audio_system - ID of audio system

Returns: audio system's label

int cw_get_character_count(void)

Brief: Return the number of characters present in character lookup table

Return the number of characters that are known to libcw. The number includes:

\[bu]

ASCII 7bit letters,

\[bu]

numerals,

\[bu]

punctuation,

\[bu]

ISO 8859-1 accented characters,

\[bu]

ISO 8859-2 accented characters,

\[bu]

non-standard procedural signal extensions to standard CW characters.

testedin::test_character_lookups()

Returns: number of characters known to libcw

void cw_list_characters(char *list)

Brief: Get list of characters present in character lookup table

Function provides a string containing all of the characters represented in library's lookup table.

The list includes:

\[bu]

ASCII 7bit letters,

\[bu]

numerals,

\[bu]

punctuation,

\[bu]

ISO 8859-1 accented characters,

\[bu]

ISO 8859-2 accented characters,

\[bu]

non-standard procedural signal extensions to standard CW characters.

list should be allocated and managed by caller. The length of list must be at least one greater than the number of characters represented in the character lookup table, returned by cw_get_character_count().

testedin::test_character_lookups()

Parameter: list - pointer to space to be filled by function

int cw_get_maximum_representation_length(void)

Brief: Get length of the longest representation

Function returns the string length of the longest representation in the character lookup table.

testedin::test_character_lookups()

Returns: a positive number - length of the longest representation

int cw_lookup_character(char c, char *representation)

Brief: Get representation of a given character

The function is depreciated, use cw_character_to_representation() instead.

Return the string representation (shape) of a given Morse code character c.

The routine returns CW_SUCCESS on success, and fills in the string pointer (representation) passed in. On failure, it returns CW_FAILURE and sets errno to ENOENT, indicating that the character c could not be found.

The length of representation buffer must be at least one greater than the length of longest representation held in the character lookup table. The largest value of length is returned by cw_get_maximum_representation_length().

Parameter: c - character to look up

Parameter: representation - pointer to space for representation of character

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

char *cw_character_to_representation(int c)

Brief: Get representation of a given character

On success return representation of a given character. Returned pointer is owned by caller of the function.

On failure function returns NULL and sets errno: ENOENT indicates that the character could not be found. ENOMEM indicates that character has been found, but function failed to strdup() representation.

testedin::test_character_lookups()

Parameter: c - character to look up

Returns: pointer to freshly allocated representation on success

Returns: NULL on failure

int cw_check_representation(const char *representation)

Brief: Check if representation of a character is valid

This function is depreciated, use cw_representation_is_valid() instead.

Check that the given string is a valid Morse representation. A valid string is one composed of only "." and "-" characters.

If representation is invalid, function returns CW_FAILURE and sets errno to EINVAL.

Parameter: representation - representation of a character to check

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

bool cw_representation_is_valid(const char *representation)

Brief: Check if representation of a character is valid

Check that the given string is a valid Morse representation. A valid string is one composed of only "." and "-" characters. This means that the function checks only if representation is error-free, and not whether the representation represents existing/defined character.

If representation is invalid, function returns false and sets errno to EINVAL.

testedin::test_representations()

Parameter: representation - representation of a character to check

Returns: true on success

Returns: false on failure

int cw_lookup_representation(const char *representation, char *c)

Brief: Get the character represented by a given Morse representation

This function is depreciated, use cw_representation_to_character() instead.

Function checks representation, and if it is valid and represents a known character, function returns CW_SUCCESS. Additionally, if c is non-NULL, function puts the looked up character in c.

c should be allocated by caller. Function assumes that c being NULL pointer is a valid situation, and can return CW_SUCCESS in such situation.

On error, function returns CW_FAILURE. errno is set to EINVAL if any character of the representation is invalid, or ENOENT to indicate that the character represented by representation could not be found.

Parameter: representation - representation of a character to look up

Parameter: c - location where to put looked up character

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_representation_to_character(const char *representation)

Brief: Return the character represented by a given Morse representation

Function checks representation, and if it is valid and represents a known character, function returns the character (a non-zero value).

On error, function returns zero. errno is set to EINVAL if any character of the representation is invalid, or ENOENT to indicate that the character represented by representation could not be found.

testedin::test_character_lookups()

Parameter: representation - representation of a character to look up

Returns: non-zero character on success

Returns: zero on failure

int cw_get_procedural_character_count(void)

Brief: Get number of procedural signals

testedin::test_prosign_lookups()

Returns: the number of characters represented in the procedural signal expansion lookup table

void cw_list_procedural_characters(char *list)

Brief: Get list of characters for which procedural expansion is available

Function returns into list a string containing all of the Morse characters for which procedural expansion is available. The length of list must be at least by one greater than the number of characters represented in the procedural signal expansion lookup table, returned by cw_get_procedural_character_count().

list is managed by caller

testedin::test_prosign_lookups()

Parameter: list - space for returned characters

int cw_get_maximum_procedural_expansion_length(void)

Brief: Get length of the longest procedural expansion

Function returns the string length of the longest expansion in the procedural signal expansion table.

testedin::test_prosign_lookups()

Returns: length

int cw_lookup_procedural_character(char c, char *expansion, int *is_usually_expanded)

Brief: Get the string expansion of a given Morse code procedural signal character

On success the function - fills expansion with the string expansion of a given Morse code procedural signal character c; - sets is_usuall_expanded to true as a display hint for the caller; - returns CW_SUCCESS.

Both expansion and expansion must be allocated and managed by caller. They can be NULL, then the function won't attempt to use them.

The length of expansion must be at least by one greater than the longest expansion held in the procedural signal character lookup table, as returned by cw_get_maximum_procedural_expansion_length().

If procedural signal character c cannot be found, the function sets errno to ENOENT and returns CW_FAILURE.

testedin::test_prosign_lookups()

Parameter: c - character to look up

Parameter: expansion - output, space to fill with expansion of the character

Parameter: is_usually_expanded - visual hint

Returns: CW_FAILURE on failure (errno is set to ENOENT)

Returns: CW_SUCCESS on success

int cw_get_maximum_phonetic_length(void)

Brief: Get maximum length of a phonetic

testedin::test_phonetic_lookups()

Returns: the string length of the longest phonetic in the phonetics lookup table

int cw_lookup_phonetic(char c, char *phonetic)

Brief: Get the phonetic of a given character

On success the routine fills in the string pointer passed in with the phonetic of given character c.

The length of phonetic must be at least one greater than the longest phonetic held in the phonetic lookup table, as returned by cw_get_maximum_phonetic_length().

If character cannot be found, the function sets errno to ENOENT.

testedin::test_phonetic_lookups()

Parameter: c - character to look up

Parameter: phonetic - output, space for phonetic of a character

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

void cw_get_speed_limits(int *min_speed, int *max_speed)

Brief: Get speed limits

Get (through function's arguments) limits on speed of morse code that can be generated by generator.

See CW_SPEED_MIN and CW_SPEED_MAX in libcw.h for values.

testedin::test_cw_get_x_limits()

Parameter: min_speed - minimal allowed speed

Parameter: max_speed - maximal allowed speed

void cw_get_frequency_limits(int *min_frequency, int *max_frequency)

Brief: Get frequency limits

Get (through function's arguments) limits on frequency that can be generated by generator.

See CW_FREQUENCY_MIN and CW_FREQUENCY_MAX in libcw.h for values.

testedin::test_cw_get_x_limits()

Parameter: min_frequency - minimal allowed frequency

Parameter: max_frequency - maximal allowed frequency

void cw_get_volume_limits(int *min_volume, int *max_volume)

Brief: Get volume limits

Get (through function's arguments) limits on volume of sound generated by generator.

See CW_VOLUME_MIN and CW_VOLUME_MAX in libcw.h for values.

testedin::test_cw_get_x_limits() testedin::test_volume_functions()

Parameter: min_volume - minimal allowed volume

Parameter: max_volume - maximal allowed volume

void cw_get_gap_limits(int *min_gap, int *max_gap)

Brief: Get gap limits

Get (through function's arguments) limits on gap in cw signal generated by generator.

See CW_GAP_MIN and CW_GAP_MAX in libcw.h for values.

testedin::test_cw_get_x_limits()

Parameter: min_gap - minimal allowed gap

Parameter: max_gap - maximal allowed gap

void cw_get_tolerance_limits(int *min_tolerance, int *max_tolerance)

Brief: Get tolerance limits

Get (through function's arguments) limits on "tolerance" parameter of generator.

See CW_TOLERANCE_MIN and CW_TOLERANCE_MAX in libcw.h for values.

testedin::test_cw_get_x_limits()

Parameter: min_tolerance - minimal allowed tolerance

Parameter: max_tolerance - maximal allowed tolerance

void cw_get_weighting_limits(int *min_weighting, int *max_weighting)

Brief: Get weighting limits

Get (through function's arguments) limits on "weighting" parameter of generator.

See CW_WEIGHTING_MIN and CW_WEIGHTING_MAX in libcw.h for values.

testedin::test_cw_get_x_limits()

Parameter: min_weighting - minimal allowed weighting

Parameter: max_weighting - maximal allowed weighting

void cw_reset_send_receive_parameters(void)

Brief: Reset send/receive parameters

Reset the library speed, frequency, volume, gap, tolerance, weighting, adaptive receive, and noise spike threshold to their initial default values: send/receive speed 12 WPM, volume 70 %, frequency 800 Hz, gap 0 dots, tolerance 50 %, and weighting 50 %.

int cw_set_send_speed(int new_value)

Brief: Set sending speed of generator

See libcw.h/CW_SPEED_{INITIAL|MIN|MAX} for initial/minimal/maximal value of send speed.

errno is set to EINVAL if new_value is out of range.

testedin::test_parameter_ranges()

Parameter: new_value - new value of send speed to be assigned to generator

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_set_receive_speed(int new_value)

Brief: Set receiving speed of receiver

See documentation of cw_set_send_speed() for more information.

See libcw.h/CW_SPEED_{INITIAL|MIN|MAX} for initial/minimal/maximal value of receive speed. errno is set to EINVAL if new_value is out of range. errno is set to EPERM if adaptive receive speed tracking is enabled.

testedin::test_parameter_ranges()

Parameter: new_value - new value of receive speed to be assigned to receiver

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_set_frequency(int new_value)

Brief: Set frequency of generator

Set frequency of sound wave generated by generator. The frequency must be within limits marked by CW_FREQUENCY_MIN and CW_FREQUENCY_MAX.

See libcw.h/CW_FREQUENCY_{INITIAL|MIN|MAX} for initial/minimal/maximal value of frequency.

errno is set to EINVAL if new_value is out of range.

testedin::test_parameter_ranges()

Parameter: new_value - new value of frequency to be assigned to generator

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_set_volume(int new_value)

Brief: Set volume of generator

Set volume of sound wave generated by generator. The volume must be within limits marked by CW_VOLUME_MIN and CW_VOLUME_MAX.

Note that volume settings are not fully possible for the console speaker. In this case, volume settings greater than zero indicate console speaker sound is on, and setting volume to zero will turn off console speaker sound.

See libcw.h/CW_VOLUME_{INITIAL|MIN|MAX} for initial/minimal/maximal value of volume. errno is set to EINVAL if new_value is out of range.

testedin::test_volume_functions() testedin::test_parameter_ranges()

Parameter: new_value - new value of volume to be assigned to generator

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_set_gap(int new_value)

Brief: Set sending gap of generator

See libcw.h/CW_GAP_{INITIAL|MIN|MAX} for initial/minimal/maximal value of gap. errno is set to EINVAL if new_value is out of range.

testedin::test_parameter_ranges()

Parameter: new_value - new value of gap to be assigned to generator

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_set_tolerance(int new_value)

Brief: Set tolerance for receiver

See libcw.h/CW_TOLERANCE_{INITIAL|MIN|MAX} for initial/minimal/maximal value of tolerance. errno is set to EINVAL if new_value is out of range.

testedin::test_parameter_ranges()

Parameter: new_value - new value of tolerance to be assigned to receiver

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_set_weighting(int new_value)

Brief: Set sending weighting for generator

See libcw.h/CW_WEIGHTING_{INITIAL|MIN|MAX} for initial/minimal/maximal value of weighting. errno is set to EINVAL if new_value is out of range.

testedin::test_parameter_ranges()

Parameter: new_value - new value of weighting to be assigned for generator

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_get_send_speed(void)

Brief: Get sending speed from generator

testedin::test_parameter_ranges()

Returns: current value of the generator's send speed

int cw_get_receive_speed(void)

Brief: Get receiving speed from receiver

testedin::test_parameter_ranges()

Returns: current value of the receiver's receive speed

int cw_get_frequency(void)

Brief: Get frequency from generator

Function returns "frequency" parameter of generator, even if the generator is stopped, or volume of generated sound is zero.

testedin::test_parameter_ranges()

Returns: current value of generator's frequency

int cw_get_volume(void)

Brief: Get sound volume from generator

Function returns "volume" parameter of generator, even if the generator is stopped.

testedin::test_volume_functions() testedin::test_parameter_ranges()

Returns: current value of generator's sound volume

int cw_get_gap(void)

Brief: Get sending gap from generator

testedin::test_parameter_ranges()

Returns: current value of generator's sending gap

int cw_get_tolerance(void)

Brief: Get tolerance from receiver

testedin::test_parameter_ranges()

Returns: current value of receiver's tolerance

int cw_get_weighting(void)

Brief: Get sending weighting from generator

testedin::test_parameter_ranges()

Returns: current value of generator's sending weighting

void cw_get_send_parameters(int *dot_usecs, int *dash_usecs,

int *end_of_element_usecs,

int *end_of_character_usecs, int *end_of_word_usecs,

int *additional_usecs, int *adjustment_usecs)

Brief: Get timing parameters for sending

Return the low-level timing parameters calculated from the speed, gap, tolerance, and weighting set. Parameter values are returned in microseconds.

Use NULL for the pointer argument to any parameter value not required.

Parameter: dot_usecs

Parameter: dash_usecs

Parameter: end_of_element_usecs

Parameter: end_of_character_usecs

Parameter: end_of_word_usecs

Parameter: additional_usecs

Parameter: adjustment_usecs

void cw_get_receive_parameters(int *dot_usecs, int *dash_usecs,

int *dot_min_usecs, int *dot_max_usecs,

int *dash_min_usecs, int *dash_max_usecs,

int *end_of_element_min_usecs,

int *end_of_element_max_usecs,

int *end_of_element_ideal_usecs,

int *end_of_character_min_usecs,

int *end_of_character_max_usecs,

int *end_of_character_ideal_usecs,

int *adaptive_threshold)

Brief: Get timing parameters for receiving, and adaptive threshold

Return the low-level timing parameters calculated from the speed, gap, tolerance, and weighting set. Parameter values are returned in microseconds.

Use NULL for the pointer argument to any parameter value not required.

Parameter: dot_usecs

Parameter: dash_usecs

Parameter: dot_min_usecs

Parameter: dot_max_usecs

Parameter: dash_min_usecs

Parameter: dash_max_usecs

Parameter: end_of_element_min_usecs

Parameter: end_of_element_max_usecs

Parameter: end_of_element_ideal_usecs

Parameter: end_of_character_min_usecs

Parameter: end_of_character_max_usecs

Parameter: end_of_character_ideal_usecs

Parameter: adaptive_threshold

int cw_set_noise_spike_threshold(int new_value)

Brief: Set noise spike threshold for receiver

Set the period shorter than which, on receive, received tones are ignored. This allows the receive tone functions to apply noise canceling for very short apparent tones. For useful results the value should never exceed the dot length of a dot at maximum speed: 20000 microseconds (the dot length at 60WPM). Setting a noise threshold of zero turns off receive tone noise canceling.

The default noise spike threshold is 10000 microseconds.

errno is set to EINVAL if new_value is out of range.

Parameter: new_value - new value of noise spike threshold to be assigned to receiver

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_get_noise_spike_threshold(void)

Brief: Get noise spike threshold from receiver

See documentation of cw_set_noise_spike_threshold() for more information

Returns: current value of receiver's threshold

void cw_block_callback(int block)

Brief: Block the callback from being called

Function blocks the callback from being called for a critical section of caller code if block is true, and unblocks the callback if block is false.

Function works by blocking SIGALRM; a block should always be matched by an unblock, otherwise the tone queue will suspend forever.

Parameter: block - pass 1 to block SIGALRM, and 0 to unblock it

int cw_register_signal_handler(int signal_number, void (*callback_func)(int))

Brief: Register a signal handler and optional callback function for given signal number

On receipt of that signal, all library features will be reset to their default states. Following the reset, if callback_func is a function pointer, the function is called; if it is SIG_DFL, the library calls exit(); and if it is SIG_IGN, the library returns from the signal handler.

This is a convenience function for clients that need to clean up library on signals, with either exit, continue, or an additional function call; in effect, a wrapper round a restricted form of sigaction.

The signal_number argument indicates which signal to catch.

On problems errno is set to EINVAL if signal_number is invalid or if a handler is already installed for that signal, or to the sigaction error code.

Parameter: signal_number

Parameter: callback_func

Returns: CW_SUCCESS - if the signal handler installs correctly

Returns: CW_FAILURE - on errors or problems

int cw_unregister_signal_handler(int signal_number)

Brief: Unregister a signal handler interception

Function removes a signal handler interception previously registered with cw_register_signal_handler().

Parameter: signal_number

Returns: true if the signal handler uninstalls correctly

Returns: false otherwise (with errno set to EINVAL or to the sigaction error code)

const char *cw_get_console_device(void)

Brief: Return char string with console device path

Returned pointer is owned by library.

Returns: char string with current console device path

const char *cw_get_soundcard_device(void)

Brief: Return char string with soundcard device name/path

Returned pointer is owned by library.

Returns: char string with current soundcard device name or device path

void cw_complete_reset(void)

Brief: Reset all library features to their default states

Clears the tone queue, receive buffers and retained state information, any current keyer activity, and any straight key activity, returns to silence, and closes soundcard and console devices. This function is suitable for calling from an application exit handler.

void cw_register_keying_callback(void (*callback_func)(void*, int),

void *callback_arg)

Brief: Register external callback function for keying

Register a callback_func function that should be called when a state of a key changes from "key open" to "key closed", or vice-versa.

The first argument passed to the registered callback function is the supplied callback_arg, if any. The second argument passed to registered callback function is the key state: CW_KEY_STATE_CLOSED (one/true) for "key closed", and CW_KEY_STATE_OPEN (zero/false) for "key open".

Calling this routine with a NULL function address disables keying callbacks. Any callback supplied will be called in signal handler context (??).

Parameter: callback_func - callback function to be called on key state changes

Parameter: callback_arg - first argument to callback_func

int cw_register_tone_queue_low_callback(void (*callback_func)(void*), void *callback_arg, int level)

Brief: Register callback for low queue state

Register a function to be called automatically by the dequeue routine whenever the tone queue falls to a given level. To be more precise: the callback is called by queue manager if, after dequeueing a tone, the manager notices that tone queue length has become equal or less than level.

callback_arg may be used to give a value passed back on callback calls. A NULL function pointer suppresses callbacks. On success, the routine returns CW_SUCCESS.

If level is invalid, the routine returns CW_FAILURE with errno set to EINVAL. Any callback supplied will be called in signal handler context.

testedin::test_tone_queue_callback()

Parameter: callback_func - callback function to be registered

Parameter: callback_arg - argument for callback_func to pass return value

Parameter: level - low level of queue triggering callback call

Returns: CW_SUCCESS on successful registration

Returns: CW_FAILURE on failure

bool cw_is_tone_busy(void)

Brief: Check if tone sender is busy

Indicate if the tone sender is busy.

Returns: true if there are still entries in the tone queue

Returns: false if the queue is empty

int cw_wait_for_tone(void)

Brief: Wait for the current tone to complete

The routine returns CW_SUCCESS on success. If called with SIGALRM blocked, the routine returns CW_FAILURE, with errno set to EDEADLK, to avoid indefinite waits.

testedin::test_tone_queue_1() testedin::test_tone_queue_2()

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_wait_for_tone_queue(void)

Brief: Wait for the tone queue to drain

The routine returns CW_SUCCESS on success. If called with SIGALRM blocked, the routine returns false, with errno set to EDEADLK, to avoid indefinite waits.

testedin::test_tone_queue_1() testedin::test_tone_queue_2() testedin::test_tone_queue_3()

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_wait_for_tone_queue_critical(int level)

Brief: Wait for the tone queue to drain until only as many tones as given in level remain queued

This routine is for use by programs that want to optimize themselves to avoid the cleanup that happens when the tone queue drains completely; such programs have a short time in which to add more tones to the queue.

The routine returns CW_SUCCESS on success. If called with SIGALRM blocked, the routine returns false, with errno set to EDEADLK, to avoid indefinite waits.

Parameter: level - low level in queue, at which to return

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

bool cw_is_tone_queue_full(void)

Brief: Indicate if the tone queue is full

testedin::test_cw_tone_queue_is_full_internal()

Returns: true if tone queue is full

Returns: false if tone queue is not full

int cw_get_tone_queue_capacity(void)

Brief: Return the number of entries the tone queue can accommodate

testedin::test_tone_queue_3() testedin::test_cw_tone_queue_get_capacity_internal()

int cw_get_tone_queue_length(void)

Brief: Return the number of entries currently pending in the tone queue

testedin::test_cw_tone_queue_length_internal() testedin::test_tone_queue_1() testedin::test_tone_queue_3()

void cw_flush_tone_queue(void)

Brief: Cancel all pending queued tones, and return to silence.

If there is a tone in progress, the function will wait until this last one has completed, then silence the tones.

This function may be called with SIGALRM blocked, in which case it will empty the queue as best it can, then return without waiting for the final tone to complete. In this case, it may not be possible to guarantee silence after the call.

int cw_queue_tone(int usecs, int frequency)

Brief: Primitive access to simple tone generation

This routine queues a tone of given duration and frequency. The routine returns CW_SUCCESS on success. If usec or frequency are invalid, it returns CW_FAILURE with errno set to EINVAL. If the sound card, console speaker, or keying function are busy, it returns CW_FAILURE with errno set to EBUSY. If the tone queue is full, it returns false with errno set to EAGAIN.

testedin::test_tone_queue_0() testedin::test_tone_queue_1() testedin::test_tone_queue_2() testedin::test_tone_queue_3()

Parameter: usecs - duration of queued tone, in microseconds

Parameter: frequency - frequency of queued tone

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

void cw_reset_tone_queue(void)

Cancel all pending queued tones, reset any queue low callback registered, and return to silence. This function is suitable for calling from an application exit handler.

int cw_send_dot(void)

cw_send_[dot|dash|character_space|word_space]()

Low level primitives, available to send single dots, dashes, character spaces, and word spaces. The dot and dash routines always append the normal inter-element gap after the tone sent. The cw_send_character_space routine sends space timed to exclude the expected prior dot/dash inter-element gap. The cw_send_word_space routine sends space timed to exclude both the expected prior dot/dash inter-element gap and the prior end of character space. These functions return true on success, or false with errno set to EBUSY or EAGAIN on error.

testedin::test_send_primitives()

int cw_send_dash(void)

See documentation of cw_send_dot() for more information

testedin::test_send_primitives()

int cw_send_character_space(void)

See documentation of cw_send_dot() for more information

testedin::test_send_primitives()

int cw_send_word_space(void)

See documentation of cw_send_dot() for more information

testedin::test_send_primitives()

int cw_send_representation(const char *representation)

Brief: Check, then send the given string as dots and dashes.

The representation passed in is assumed to be a complete Morse character; that is, all post-character delays will be added when the character is sent.

On success, the routine returns CW_SUCCESS. On failure, it returns CW_FAILURE, with errno set to EINVAL if any character of the representation is invalid, EBUSY if the sound card, console speaker, or keying system is busy, or EAGAIN if the tone queue is full, or if there is insufficient space to queue the tones or the representation.

testedin::test_representations()

Parameter: representation - representation to send

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_send_representation_partial(const char *representation)

Brief: Check, then send the given string as dots and dashes

The representation passed in is assumed to be only part of a larger Morse representation; that is, no post-character delays will be added when the character is sent.

On success, the routine returns CW_SUCCESS. On failure, it returns CW_FAILURE, with errno set to EINVAL if any character of the representation is invalid, EBUSY if the sound card, console speaker, or keying system is busy, or EAGAIN if the tone queue is full, or if there is insufficient space to queue the tones for the representation.

testedin::test_representations()

bool cw_character_is_valid(char c)

Brief: Checks that the given character is validly sendable in Morse

Function sets errno to ENOENT on failure.

testedin::test_validate_character_and_string()

Parameter: c - character to check

Returns: CW_SUCCESS if character is valid

Returns: CW_FAILURE if character is invalid

int cw_send_character(char c)

Brief: Lookup, and send a given ASCII character as Morse

The end of character delay is appended to the Morse sent.

On success, the routine returns CW_SUCCESS. On failure, it returns CW_FAILURE, with errno set to ENOENT if the given character c is not a valid Morse character, EBUSY if the sound card, console speaker, or keying system is busy, or EAGAIN if the tone queue is full, or if there is insufficient space to queue the tones for the character.

This routine returns as soon as the character has been successfully queued for sending; that is, almost immediately. The actual sending happens in background processing. See cw_wait_for_tone() and cw_wait_for_tone_queue() for ways to check the progress of sending.

testedin::test_send_character_and_string()

Parameter: c - character to send

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_send_character_partial(char c)

Brief: Lookup, and send a given ASCII character as Morse code

"partial" means that the "end of character" delay is not appended to the Morse code sent by the function, to support the formation of combination characters.

On success, the routine returns CW_SUCCESS. On error, it returns CW_FAILURE, with errno set to ENOENT if the given character is not a valid Morse character, EBUSY if the sound card, console speaker, or keying system is busy, or EAGAIN if the tone queue is full, or if there is insufficient space to queue the tones for the character.

This routine queues its arguments for background processing. See cw_send_character() for details of how to check the queue status.

Parameter: c - character to send

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

bool cw_string_is_valid(const char *string)

Brief: Validate a string

Check that each character in the given string is valid and can be sent by libcw as a Morse character.

Function sets errno to EINVAL on failure

testedin::test_validate_character_and_string()

Parameter: string - string to check

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_send_string(const char *string)

Brief: Send a given ASCII string in Morse code

errno is set to ENOENT if any character in the string is not a valid Morse character, EBUSY if the sound card, console speaker, or keying system is in use by the iambic keyer or the straight key, or EAGAIN if the tone queue is full. If the tone queue runs out of space part way through queueing the string, the function returns EAGAIN. However, an indeterminate number of the characters from the string will have already been queued. For safety, clients can ensure the tone queue is empty before queueing a string, or use cw_send_character() if they need finer control.

This routine queues its arguments for background processing, the actual sending happens in background processing. See cw_wait_for_tone() and cw_wait_for_tone_queue() for ways to check the progress of sending.

testedin::test_send_character_and_string()

Parameter: string - string to send

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

void cw_get_receive_statistics(double *dot_sd, double *dash_sd,

double *element_end_sd, double *character_end_sd)

Brief: Calculate and return receive timing statistics

These statistics may be used to obtain a measure of the accuracy of received CW. The values dot_sd and dot_sd contain the standard deviation of dot and dash lengths from the ideal values, and element_end_sd and element_end_sd the deviations for inter element and inter character spacing. Statistics are held for all timings in a 256 element circular buffer. If any statistic cannot be calculated, because no records for it exist, the returned value is 0.0. Use NULL for the pointer argument to any statistic not required.

Parameter: dot_sd

Parameter: dash_sd

Parameter: element_end_sd

Parameter: character_end_sd

void cw_reset_receive_statistics(void)

Brief: Clear the receive statistics buffer

Clear the receive statistics buffer by removing all records from it and returning it to its initial default state.

void cw_enable_adaptive_receive(void)

Brief: Enable adaptive receive speed tracking

If adaptive speed tracking is enabled, the receive functions will attempt to automatically adjust the receive speed setting to match the speed of the incoming Morse code. If it is disabled, the receive functions will use fixed speed settings, and reject incoming Morse which is not at the expected speed.

Adaptive speed tracking uses a moving average of the past four elements as its baseline for tracking speeds. The default state is adaptive speed tracking disabled.

void cw_disable_adaptive_receive(void)

Brief: Disable adaptive receive speed tracking

See documentation of cw_enable_adaptive_receive() for more information

bool cw_get_adaptive_receive_state(void)

Brief: Get adaptive receive speed tracking flag

The function returns state of "adaptive receive enabled" flag. See documentation of cw_enable_adaptive_receive() for more information

Returns: true if adaptive speed tracking is enabled

Returns: false otherwise

int cw_start_receive_tone(const struct timeval *timestamp)

Brief: Mark beginning of receive tone

Called on the start of a receive tone. If the timestamp is NULL, the current timestamp is used as beginning of tone.

On error the function returns CW_FAILURE, with errno set to ERANGE if the call is directly after another cw_start_receive_tone() call or if an existing received character has not been cleared from the buffer, or EINVAL if the timestamp passed in is invalid.

Parameter: timestamp

Returns: CW_SUCCESS on success

Returns: CW_FAILURE otherwise (with errno set)

int cw_end_receive_tone(const struct timeval *timestamp)

Brief: Mark end of tone

Called on the end of a received tone.

If the timestamp is NULL, the current time is used as timestamp of end of tone.

On success, the routine adds a dot or dash to the receiver's representation buffer, and returns CW_SUCCESS.

On failure, it returns CW_FAIURE, with errno set to: ERANGE if the call was not preceded by a cw_start_receive_tone() call, EINVAL if the timestamp passed in is not valid, ENOENT if the tone length was out of bounds for the permissible dot and dash lengths and fixed speed receiving is selected, ENOMEM if the receiver's representation buffer is full, EAGAIN if the tone was shorter than the threshold for noise and was therefore ignored.

Parameter: timestamp

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_receive_buffer_dot(const struct timeval *timestamp)

Brief: Add a dot to the receiver's representation buffer

Documentation for both cw_receive_buffer_dot() and cw_receive_buffer_dash():

Since we can't add an element to the buffer without any accompanying timing information, the functions accepts timestamp of the "end of element" event. If the timestamp is NULL, the current timestamp is used.

These routines are for client code that has already determined whether a dot or dash was received by a method other than calling the routines cw_start_receive_tone() and cw_end_receive_tone().

On success, the relevant element is added to the receiver's representation buffer.

On failure, the routines return CW_FAILURE, with errno set to ERANGE if preceded by a cw_start_receive_tone call with no matching cw_end_receive_tone or if an error condition currently exists within the receiver's buffer, or ENOMEM if the receiver's representation buffer is full.

Parameter: timestamp - timestamp of "end of dot" event

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_receive_buffer_dash(const struct timeval *timestamp)

Brief: Add a dash to the receiver's representation buffer

See documentation of cw_receive_buffer_dot() for more information.

Parameter: timestamp - timestamp of "end of dash" event

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_receive_representation(const struct timeval *timestamp,

/* out */ char *representation,

/* out */ bool *is_end_of_word, /* out */ bool *is_error)

Brief: Get the current buffered representation from the receiver's representation buffer

On success the function fills in representation with the contents of the current representation buffer and returns CW_SUCCESS.

On failure, it returns CW_FAILURE and sets errno to: ERANGE if not preceded by a cw_end_receive_tone call, a prior successful cw_receive_representation call, or a prior cw_receive_buffer_dot or cw_receive_buffer_dash, EINVAL if the timestamp passed in is invalid, EAGAIN if the call is made too early to determine whether a complete representation has yet been placed in the buffer (that is, less than the inter-character gap period elapsed since the last cw_end_receive_tone or cw_receive_buffer_dot/dash call). This is not a *hard* error, just an information that the caller should try to get the representation later.

is_end_of_word indicates that the delay after the last tone received is longer that the inter-word gap.

is_error indicates that the representation was terminated by an error condition.

TODO: the function should be called cw_receiver_get_representation().

TODO: why we pass timestamp to the function when all we want from it is a representation from representation buffer? It seems that the function can be called with timestamp for last event, i.e. on end of last space. "last space" may mean space after last element (dot/dash) in a character, or a space between two characters, or (a bit different case) a space between words. Timestamp for end of space would be the same timestamp as for beginning of new tone (?).

testedin::test_helper_receive_tests()

Parameter: timestamp - timestamp of event that ends "end-of-character" space or "end-of-word" space

Parameter: representation - buffer for representation (output parameter)

Parameter: is_end_of_word - buffer for "is end of word" state (output parameter)

Parameter: is_error - buffer for "error" state (output parameter)

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_receive_character(const struct timeval *timestamp,

/* out */ char *c,

/* out */ bool *is_end_of_word, /* out */ bool *is_error)

Brief: Get a current character

Function returns the character currently stored in receiver's representation buffer.

On success the function returns CW_SUCCESS, and fills c with the contents of the current representation buffer, translated into a character.

On failure the function returns CW_FAILURE, with errno set to:

ERANGE if not preceded by a cw_end_receive_tone() call, a prior successful cw_receive_character() call, or a cw_receive_buffer_dot() or cw_receive_buffer_dash() call, EINVAL if the timestamp passed in is invalid, or EAGAIN if the call is made too early to determine whether a complete character has yet been placed in the buffer (that is, less than the inter-character gap period elapsed since the last cw_end_receive_tone() or cw_receive_buffer_dot/dash call). ENOENT if character stored in receiver cannot be recognized as valid

is_end_of_word indicates that the delay after the last tone received is longer that the inter-word gap.

is_error indicates that the character was terminated by an error condition.

testedin::test_helper_receive_tests()

Parameter: timestamp - timestamp of event that ends "end-of-character" space or "end-of-word" space

Parameter: c - buffer for character (output parameter)

Parameter: is_end_of_word - buffer for "is end of word" state (output parameter)

Parameter: is_error - buffer for "error" state (output parameter)

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

void cw_clear_receive_buffer(void)

Brief: Clear receiver's representation buffer

Clears the receiver's representation buffer, resets receiver's internal state. This prepares the receiver to receive tones again.

This routine must be called after successful, or terminating, cw_receive_representation() or cw_receive_character() calls, to clear the states and prepare the buffer to receive more tones.

int cw_get_receive_buffer_capacity(void)

Brief: Get the number of elements (dots/dashes) the receiver's buffer can accommodate

The maximum number of elements written out by cw_receive_representation() is the capacity + 1, the extra character being used for the terminating NUL.

Returns: number of elements that can be stored in receiver's representation buffer

int cw_get_receive_buffer_length(void)

Brief: Get the number of elements (dots/dashes) currently pending in the receiver's representation buffer

testedin::test_helper_receive_tests()

Returns: number of elements in receiver's representation buffer

void cw_reset_receive(void)

Brief: Clear receive data

Clear the receiver's representation buffer, statistics, and any retained receiver's state. This function is suitable for calling from an application exit handler.

void cw_enable_iambic_curtis_mode_b(void)

Brief: Enable iambic Curtis mode B

Normally, the iambic keying functions will emulate Curtis 8044 Keyer mode A. In this mode, when both paddles are pressed together, the last dot or dash being sent on release is completed, and nothing else is sent. In mode B, when both paddles are pressed together, the last dot or dash being sent on release is completed, then an opposite element is also sent. Some operators prefer mode B, but timing is more critical in this mode. The default mode is Curtis mode A.

void cw_disable_iambic_curtis_mode_b(void)

See documentation of cw_enable_iambic_curtis_mode_b() for more information

int cw_get_iambic_curtis_mode_b_state(void)

See documentation of cw_enable_iambic_curtis_mode_b() for more information

int cw_notify_keyer_paddle_event(int dot_paddle_state,

int dash_paddle_state)

Brief: Inform about changed state of iambic keyer's paddles

Function informs the library that the iambic keyer paddles have changed state. The new paddle states are recorded, and if either transition from false to true, paddle latches, for iambic functions, are also set.

On success, the routine returns CW_SUCCESS. On failure, it returns CW_FAILURE, with errno set to EBUSY if the tone queue or straight key are using the sound card, console speaker, or keying system.

If appropriate, this routine starts the keyer functions sending the relevant element. Element send and timing occurs in the background, so this routine returns almost immediately. See cw_keyer_element_wait() and cw_keyer_wait() for details about how to check the current status of iambic keyer background processing.

testedin::test_keyer()

Parameter: dot_paddle_state

Parameter: dash_paddle_state

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_notify_keyer_dot_paddle_event(int dot_paddle_state)

Brief: Change state of dot paddle

Alter the state of just one of the two iambic keyer paddles. The other paddle state of the paddle pair remains unchanged.

See cw_keyer_paddle_event() for details of iambic keyer background processing, and how to check its status.

Parameter: dot_paddle_state

int cw_notify_keyer_dash_paddle_event(int dash_paddle_state)

See documentation of cw_notify_keyer_dot_paddle_event() for more information

void cw_get_keyer_paddles(int *dot_paddle_state, int *dash_paddle_state)

Brief: Get the current saved states of the two paddles

testedin::test_keyer()

Parameter: dot_paddle_state

Parameter: dash_paddle_state

void cw_get_keyer_paddle_latches(int *dot_paddle_latch_state,

int *dash_paddle_latch_state)

Brief: Get the current states of paddle latches

Function returns the current saved states of the two paddle latches. A paddle latches is set to true when the paddle state becomes true, and is cleared if the paddle state is false when the element finishes sending.

Parameter: dot_paddle_latch_state

Parameter: dash_paddle_latch_state

bool cw_is_keyer_busy(void)

Brief: Check if a keyer is busy

Returns: true if keyer is busy

Returns: false if keyer is not busy

int cw_wait_for_keyer_element(void)

Brief: Wait for end of element from the keyer

Waits until the end of the current element, dot or dash, from the keyer.

On error the function returns CW_FAILURE, with errno set to EDEADLK if SIGALRM is blocked.

testedin::test_keyer()

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

int cw_wait_for_keyer(void)

Brief: Wait for the current keyer cycle to complete

The routine returns CW_SUCCESS on success. On error, it returns CW_FAILURE, with errno set to EDEADLK if SIGALRM is blocked or if either paddle state is true.

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

void cw_reset_keyer(void)

Brief: Reset iambic keyer data

Clear all latches and paddle states of iambic keyer, return to Curtis 8044 Keyer mode A, and return to silence. This function is suitable for calling from an application exit handler.

int cw_notify_straight_key_event(int key_state)

Brief: Inform the library that the straight key has changed state

This routine returns CW_SUCCESS on success. On error, it returns CW_FAILURE, with errno set to EBUSY if the tone queue or iambic keyer are using the sound card, console speaker, or keying control system. If key_state indicates no change of state, the call is ignored.

key_state may be either CW_KEY_STATE_OPEN (false) or CW_KEY_STATE_CLOSED (true).

testedin::test_straight_key()

Parameter: key_state - state of straight key

int cw_get_straight_key_state(void)

Brief: Get saved state of straight key

Returns the current saved state of the straight key.

testedin::test_straight_key()

Returns: CW_KEY_STATE_CLOSED (true) if the key is down

Returns: CW_KEY_STATE_OPEN (false) if the key up

bool cw_is_straight_key_busy(void)

Brief: Check if the straight key is busy

This routine is just a pseudonym for cw_get_straight_key_state(), and exists to fill a hole in the API naming conventions.

testedin::test_straight_key()

Returns: true if the straight key is busy

Returns: false if the straight key is not busy

void cw_reset_straight_key(void)

Brief: Clear the straight key state, and return to silence

This function is suitable for calling from an application exit handler.

const char *cw_generator_get_audio_system_label(void)

Brief: Get a readable label of current audio system

The function returns one of following strings: None, Null, Console, OSS, ALSA, PulseAudio, Soundcard

Returns: audio system's label

int cw_generator_new(int audio_system, const char *device)

Brief: Create new generator

Allocate memory for new generator data structure, set up default values of some of the generator's properties. The function does not start the generator (generator does not produce a sound), you have to use cw_generator_start() for this.

Notice that the function doesn't return a generator variable. There is at most one generator variable at any given time. You can't have two generators. In some future version of the library the function will return pointer to newly allocated generator, and then you could have as many of them as you want, but not yet.

audio_system can be one of following: NULL, console, OSS, ALSA, PulseAudio, soundcard. See "enum cw_audio_systems" in libcw.h for exact names of symbolic constants.

Parameter: audio_system - audio system to be used by the generator

Parameter: device - name of audio device to be used; if NULL then library will use default device.

void cw_generator_delete(void)

Brief: Deallocate generator

Deallocate/destroy generator data structure created with call to cw_generator_new(). You can't start nor use the generator after the call to this function.

int cw_generator_start(void)

Brief: Start a generator

Start producing tones using generator created with cw_generator_new(). The source of tones is a tone queue associated with the generator. If the tone queue is empty, the generator will wait for new tones to be queued.

Returns: CW_FAILURE on errors

Returns: CW_SUCCESS on success

void cw_generator_stop(void)

Brief: Shut down a generator

Silence tone generated by generator (level of generated sine wave is set to zero, with falling slope), and shut the generator down.

The shutdown does not erase generator's configuration.

If you want to have this generator running again, you have to call cw_generator_start().

int cw_generator_set_tone_slope(cw_gen_t *gen, int slope_shape, int slope_usecs)

Brief: Set parameters of tones generated by generator

Most of variables related to slope of tones is in tone data type, but there are still some variables that are generator-specific, as they are common for all tones. This function sets these variables.

One of the variables is a table of amplitudes for every point in slope. Values in the table are generated only once, when parameters of the slope change. This saves us from re-calculating amplitudes of slope for every tone. With the table at hand we can simply look up an amplitude of point of slope in the table of amplitudes.

You can pass -1 as value of slope_shape or slope_shape, the function will then either resolve correct values of its arguments, or will leave related parameters of slope unchanged.

The function should be called every time one of following parameters change:

\[bu]

shape of slope,

\[bu]

length of slope,

\[bu]

generator's sample rate,

\[bu]

generator's volume.

There are four supported shapes of slopes:

\[bu]

linear (the only one supported by libcw until version 4.1.1),

\[bu]

raised cosine (supposedly the most desired shape),

\[bu]

sine,

\[bu]

rectangular.

Use CW_TONE_SLOPE_SHAPE_* symbolic names as values of slope_shape.

FIXME: first argument of this public function is gen, but no function provides access to generator variable.

Parameter: gen - generator for which to set tone slope parameters

Parameter: slope_shape - shape of slope: linear, raised cosine, sine, rectangular

Parameter: slope_usecs - length of slope, in microseconds

Returns: CW_SUCCESS on success

Returns: CW_FAILURE on failure

unsigned int test_cw_tone_queue_test_capacity1(void)

Brief: Test "capacity" property of tone queue

Function tests "capacity" property of tone queue, and also tests related properties: head and tail.

In this function it is done by first enqueueing N known tones to a tone queue using cw_tone_queue_enqueue_internal(), and then "manually" checking content of tone queue to be sure that all the tones are in place.

tests::cw_tone_queue_enqueue_internal()

unsigned int test_cw_tone_queue_test_capacity2(void)

Brief: Test "capacity" property of tone queue

Function tests "capacity" property of tone queue, and also tests related properties: head and tail.

In this function it is done by first enqueueing N known tones to a tone queue using cw_tone_queue_enqueue_internal(), then dequeueing the tones with cw_tone_queue_dequeue_internal() and then checking that enqueued tones are the ones that we were expecting to get.

tests::cw_tone_queue_enqueue_internal()

tests::cw_tone_queue_dequeue_internal()

int test_cw_tone_queue_capacity_test_init(cw_tone_queue_t *tq, uint32_t capacity, uint32_t high_water_mark, int head_shift)

Brief: Initialize tone queue for tests of capacity

Initialize given queue for tests of capacity of tone queue, and of related parameters of the tq: head and tail.

First three function parameters are rather boring. What is interesting is the fourth parameter: head_shift.

In general the behaviour of tone queue (a circular list) should be independent of initial position of queue's head (i.e. from which position in the queue we start adding new elements to the queue).

By initializing the queue with different initial positions of head pointer, we can test this assertion about irrelevance of initial head position.

tests::cw_tone_queue_set_capacity_internal()

Parameter: tq - tone queue to test

Parameter: capacity - intended capacity of tone queue

Parameter: high_water_mark - high water mark to be set for tone queue

Parameter: head_shift - position of first element that will be inserted in empty queue

NOTES

Despite the fact that this manual page constantly and consistently refers to Morse code elements as dots and dashes, DO NOT think in these terms when trying to learn Morse code. Always think of them as 'dit's and 'dah's.

libcw uses system itimers for its internal timing. On most UNIX flavours, itimers are not guaranteed to signal a program exactly at the specified time, and they generally offer a resolution only as good as the normal system 'clock tick' resolution. An itimer SIGALRM usually falls on a system clock tick, making it accurate to no better than 10mS on a typical 100Hz kernel.

The effect of this is that an itimer period is generally either exactly as specified, or, more likely, slightly longer. At higher WPM settings, the cumulative effect of this affects timing accuracy, because at higher speeds, there are fewer 10mS clock ticks in a dot period. For example, at 12 WPM, the dot length is 100mS, enough to contain five kernel clock ticks; at 60 WPM, the dot length is 20mS, or just two kernel clock ticks. So at higher speeds, the effect of itimer resolutions becomes more pronounced.

RELATED TO libcw…

Man pages for cw(7,LOCAL), cw(1,LOCAL), cwgen(1,LOCAL), cwcp(1,LOCAL), and xcwcp(1,LOCAL).