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 
21 /**
22    \file libcw_gen.c
23 
24    \brief Generate pcm samples according to tones from tone queue, and
25    send them to audio sink.
26 
27    Functions operating on one of core elements of libcw: a generator.
28 
29    Generator is an object that has access to audio sink (soundcard,
30    console buzzer, null audio device) and that can play dots and
31    dashes using the audio sink.
32 
33    You can request generator to produce audio by using *_play_*()
34    functions.
35 
36    The inner workings of the generator seem to be quite simple:
37    1. dequeue tone from tone queue
38    2. recalculate tone length in usecs into length in samples
39    3. for every sample in tone, calculate sine wave sample and
40       put it in generator's constant size buffer
41    4. if buffer is full of sine wave samples, push it to audio sink
42    5. since buffer is shorter than (almost) any tone, you will
43       recalculate contents of the buffer and push it to audio sink
44       multiple times per tone
45    6. if you iterated over all samples in tone, but you still didn't
46       fill up that last buffer, go to step #1
47    7. if there are no more tones in queue, pad the buffer with silence,
48       and push the buffer to audio sink.
49 
50    Looks simple, right? But it's the little details that ruin it all.
51    One of the details is tone's slopes.
52 */
53 
54 
55 
56 
57 
58 #include "config.h"
59 
60 #include <stdlib.h>
61 #include <unistd.h>
62 #include <stdbool.h>
63 #include <math.h>
64 #include <signal.h>
65 #include <errno.h>
66 #include <inttypes.h> /* uint32_t */
67 
68 #if defined(HAVE_STRING_H)
69 # include <string.h>
70 #endif
71 
72 #if defined(HAVE_STRINGS_H)
73 # include <strings.h>
74 #endif
75 
76 
77 
78 
79 
80 #include "libcw_gen.h"
81 #include "libcw_debug.h"
82 #include "libcw_utils.h"
83 #include "libcw_signal.h"
84 #include "libcw_data.h"
85 
86 #include "libcw_null.h"
87 #include "libcw_console.h"
88 #include "libcw_oss.h"
89 
90 
91 
92 
93 
94 #ifndef M_PI  /* C99 may not define M_PI */
95 #define M_PI  3.14159265358979323846
96 #endif
97 
98 
99 
100 
101 
102 /* From libcw_debug.c. */
103 extern cw_debug_t cw_debug_object;
104 extern cw_debug_t cw_debug_object_ev;
105 extern cw_debug_t cw_debug_object_dev;
106 
107 
108 
109 
110 
111 /* Most of audio systems (excluding console) should be configured to
112    have specific sample rate. Some audio systems (with connection with
113    given hardware) can support several different sample rates. Values of
114    supported sample rates are standardized. Here is a list of them to be
115    used by this library.
116    When the library configures given audio system, it tries if the system
117    will accept a sample rate from the table, starting from the first one.
118    If a sample rate is accepted, rest of sample rates is not tested anymore. */
119 const unsigned int cw_supported_sample_rates[] = {
120 	44100,
121 	48000,
122 	32000,
123 	22050,
124 	16000,
125 	11025,
126 	 8000,
127 	    0 /* guard */
128 };
129 
130 
131 
132 
133 
134 /* Every audio system opens an audio device: a default device, or some
135    other device. Default devices have their default names, and here is
136    a list of them. It is indexed by values of "enum cw_audio_systems". */
137 static const char *default_audio_devices[] = {
138 	(char *) NULL,          /* CW_AUDIO_NONE */
139 	CW_DEFAULT_NULL_DEVICE, /* CW_AUDIO_NULL */
140 	CW_DEFAULT_CONSOLE_DEVICE,
141 	CW_DEFAULT_OSS_DEVICE,
142 	CW_DEFAULT_ALSA_DEVICE,
143 	CW_DEFAULT_PA_DEVICE,
144 	(char *) NULL }; /* just in case someone decided to index the table with CW_AUDIO_SOUNDCARD */
145 
146 
147 
148 
149 
150 /* Generic constants - common for all audio systems (or not used in some of systems). */
151 
152 static const long int CW_AUDIO_VOLUME_RANGE = (1 << 15);  /* 2^15 = 32768 */
153 static const int      CW_AUDIO_SLOPE_LEN = 5000;          /* Length of a single slope (rising or falling) in standard tone. [us] */
154 
155 /* Shortest length of time (in microseconds) that is used by libcw for
156    idle waiting and idle loops. If a libcw function needs to wait for
157    something, or make an idle loop, it should call
158    usleep(N * gen->quantum_len)
159 
160    This is also length of a single "forever" tone. */
161 static const int CW_AUDIO_QUANTUM_LEN_INITIAL = 100;  /* [us] */
162 
163 
164 
165 
166 
167 static int   cw_gen_new_open_internal(cw_gen_t *gen, int audio_system, const char *device);
168 static void *cw_gen_dequeue_and_play_internal(void *arg);
169 static int   cw_gen_calculate_sine_wave_internal(cw_gen_t *gen, cw_tone_t *tone);
170 static int   cw_gen_calculate_amplitude_internal(cw_gen_t *gen, cw_tone_t *tone);
171 static int   cw_gen_write_to_soundcard_internal(cw_gen_t *gen, cw_tone_t *tone, int queue_rv);
172 static int   cw_gen_play_valid_character_internal(cw_gen_t *gen, char character, int partial);
173 static void  cw_gen_recalculate_slopes_internal(cw_gen_t *gen);
174 
175 
176 
177 
178 
179 /**
180    \brief Get a copy of readable label of current audio system
181 
182    Get a copy of human-readable string describing audio system
183    associated currently with given \p gen.
184 
185    The function returns newly allocated pointer to one of following
186    strings: "None", "Null", "Console", "OSS", "ALSA", "PulseAudio",
187    "Soundcard".
188 
189    The returned pointer is owned by caller.
190 
191    Notice that the function returns a new pointer to newly allocated
192    string. cw_generator_get_audio_system_label() returns a pointer to
193    static string owned by library.
194 
195    \param gen - generator for which to check audio system label
196 
197    \return audio system's label
198 */
cw_gen_get_audio_system_label_internal(cw_gen_t * gen)199 char *cw_gen_get_audio_system_label_internal(cw_gen_t *gen)
200 {
201 	char *s = strdup(cw_get_audio_system_label(gen->audio_system));
202 	if (!s) {
203 		cw_vdm ("failed to strdup() audio system label for audio system %d\n", gen->audio_system);
204 	}
205 
206 	return s;
207 }
208 
209 
210 
211 
212 
213 /**
214    \brief Start a generator
215 */
cw_gen_start_internal(cw_gen_t * gen)216 int cw_gen_start_internal(cw_gen_t *gen)
217 {
218 	gen->phase_offset = 0.0;
219 
220 	/* This should be set to true before launching
221 	   cw_gen_dequeue_and_play_internal(), because loop in the
222 	   function run only when the flag is set. */
223 	gen->do_dequeue_and_play = true;
224 
225 	gen->client.thread_id = pthread_self();
226 
227 	if (gen->audio_system == CW_AUDIO_NULL
228 	    || gen->audio_system == CW_AUDIO_CONSOLE
229 	    || gen->audio_system == CW_AUDIO_OSS
230 	    || gen->audio_system == CW_AUDIO_ALSA
231 	    || gen->audio_system == CW_AUDIO_PA) {
232 
233 		/* cw_gen_dequeue_and_play_internal() is THE
234 		   function that does the main job of generating
235 		   tones. */
236 		int rv = pthread_create(&gen->thread.id, &gen->thread.attr,
237 					cw_gen_dequeue_and_play_internal,
238 					(void *) gen);
239 		if (rv != 0) {
240 			gen->do_dequeue_and_play = false;
241 
242 			cw_debug_msg ((&cw_debug_object), CW_DEBUG_STDLIB, CW_DEBUG_ERROR,
243 				      "libcw: failed to create %s generator thread", cw_get_audio_system_label(gen->audio_system));
244 			return CW_FAILURE;
245 		} else {
246 			gen->thread.running = true;
247 
248 			/* For some yet unknown reason you have to put
249 			   usleep() here, otherwise a generator may
250 			   work incorrectly */
251 			usleep(100000);
252 #ifdef LIBCW_WITH_DEV
253 			cw_dev_debug_print_generator_setup(gen);
254 #endif
255 			return CW_SUCCESS;
256 		}
257 	} else {
258 		gen->do_dequeue_and_play = false;
259 
260 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
261 			      "libcw: unsupported audio system %d", gen->audio_system);
262 		return CW_FAILURE;
263 	}
264 }
265 
266 
267 
268 
269 
270 /**
271    \brief Set audio device name or path
272 
273    Set path to audio device, or name of audio device. The path/name
274    will be associated with given generator \p gen, and used when opening
275    audio device.
276 
277    Use this function only when setting up a generator.
278 
279    Function creates its own copy of input string.
280 
281    \param gen - generator to be updated
282    \param device - device to be assigned to generator \p gen
283 
284    \return CW_SUCCESS on success
285    \return CW_FAILURE on errors
286 */
cw_gen_set_audio_device_internal(cw_gen_t * gen,const char * device)287 int cw_gen_set_audio_device_internal(cw_gen_t *gen, const char *device)
288 {
289 	/* this should be NULL, either because it has been
290 	   initialized statically as NULL, or set to
291 	   NULL by generator destructor */
292 	assert (!gen->audio_device);
293 	assert (gen->audio_system != CW_AUDIO_NONE);
294 
295 	if (gen->audio_system == CW_AUDIO_NONE) {
296 		gen->audio_device = (char *) NULL;
297 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
298 			      "libcw: no audio system specified");
299 		return CW_FAILURE;
300 	}
301 
302 	if (device) {
303 		gen->audio_device = strdup(device);
304 	} else {
305 		gen->audio_device = strdup(default_audio_devices[gen->audio_system]);
306 	}
307 
308 	if (!gen->audio_device) {
309 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_STDLIB, CW_DEBUG_ERROR,
310 			      "libcw: malloc()");
311 		return CW_FAILURE;
312 	} else {
313 		return CW_SUCCESS;
314 	}
315 }
316 
317 
318 
319 
320 
321 /**
322    \brief Silence the generator
323 
324    Force an audio sink currently used by generator \p gen to go
325    silent.
326 
327    The function does not clear/flush tone queue, nor does it stop the
328    generator. It just makes sure that audio sink (console / OSS / ALSA
329    / PulseAudio) does not produce a sound of any frequency and any
330    volume.
331 
332    You probably want to call cw_tq_flush_internal(gen->tq) before
333    calling this function.
334 
335    \param gen - generator using an audio sink that should be silenced
336 
337    \return CW_SUCCESS on success
338    \return CW_FAILURE on failure to silence an audio sink
339 */
cw_gen_silence_internal(cw_gen_t * gen)340 int cw_gen_silence_internal(cw_gen_t *gen)
341 {
342 	if (!gen) {
343 		/* this may happen because the process of finalizing
344 		   usage of libcw is rather complicated; this should
345 		   be somehow resolved */
346 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_WARNING,
347 			      "libcw: called the function for NULL generator");
348 		return CW_SUCCESS;
349 	}
350 
351 	if (!(gen->thread.running)) {
352 		/* Silencing a generator means enqueueing and playing
353 		   a tone with zero frequency.  We shouldn't do this
354 		   when a "dequeue-and-play-a-tone" function is not
355 		   running (anymore). This is not an error situation,
356 		   so return CW_SUCCESS. */
357 		return CW_SUCCESS;
358 	}
359 
360 	/* Somewhere there may be a key in "down" state and we need to
361 	   make it go "up", regardless of audio sink (even for
362 	   CDW_AUDIO_NULL!). Otherwise the key may stay in "down"
363 	   state forever. */
364 	cw_tone_t tone;
365 	CW_TONE_INIT(&tone, 0, gen->quantum_len, CW_SLOPE_MODE_NO_SLOPES);
366 	int status = cw_tq_enqueue_internal(gen->tq, &tone);
367 
368 	if (gen->audio_system == CW_AUDIO_NULL
369 	    || gen->audio_system == CW_AUDIO_OSS
370 	    || gen->audio_system == CW_AUDIO_ALSA
371 	    || gen->audio_system == CW_AUDIO_PA) {
372 
373 		/* Allow some time for playing the last tone. */
374 		usleep(2 * gen->quantum_len);
375 
376 	} else if (gen->audio_system == CW_AUDIO_CONSOLE) {
377 		/* sine wave generation should have been stopped
378 		   by a code generating dots/dashes, but
379 		   just in case...
380 
381 		   TODO: is it still necessary after adding the
382 		   quantum of silence above? */
383 		cw_console_silence(gen);
384 	} else {
385 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_ERROR,
386 			      "libcw: called silence() function for generator without audio system specified");
387 	}
388 
389 	if (gen->audio_system == CW_AUDIO_ALSA) {
390 		/* "Stop a PCM dropping pending frames. " */
391 		cw_alsa_drop(gen);
392 	}
393 
394 	//gen->do_dequeue_and_play = false;
395 
396 	return status;
397 }
398 
399 
400 
401 
402 
403 /**
404    \brief Create new generator
405 
406    testedin::test_cw_gen_new_delete_internal()
407 */
cw_gen_new_internal(int audio_system,const char * device)408 cw_gen_t *cw_gen_new_internal(int audio_system, const char *device)
409 {
410 #ifdef LIBCW_WITH_DEV
411 	fprintf(stderr, "libcw build %s %s\n", __DATE__, __TIME__);
412 #endif
413 
414 	cw_assert (audio_system != CW_AUDIO_NONE, "can't create generator with audio system \"NONE\"");
415 
416 	cw_gen_t *gen = (cw_gen_t *) malloc(sizeof (cw_gen_t));
417 	if (!gen) {
418 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_STDLIB, CW_DEBUG_ERROR,
419 			      "libcw: malloc()");
420 		return (cw_gen_t *) NULL;
421 	}
422 
423 	gen->tq = cw_tq_new_internal();
424 	if (!gen->tq) {
425 		cw_gen_delete_internal(&gen);
426 		return (cw_gen_t *) NULL;
427 	} else {
428 		/* Because libcw_tq.c/cw_tq_enqueue_internal()/pthread_kill(tq->gen->thread.id, SIGALRM); */
429 		gen->tq->gen = gen;
430 	}
431 
432 	gen->audio_device = NULL;
433 	//gen->audio_system = audio_system;
434 	gen->audio_device_is_open = false;
435 	gen->dev_raw_sink = -1;
436 
437 
438 	/* Essential sending parameters. */
439 	gen->send_speed = CW_SPEED_INITIAL,
440 	gen->frequency = CW_FREQUENCY_INITIAL;
441 	gen->volume_percent = CW_VOLUME_INITIAL;
442 	gen->volume_abs = (gen->volume_percent * CW_AUDIO_VOLUME_RANGE) / 100;
443 	gen->gap = CW_GAP_INITIAL;
444 	gen->weighting = CW_WEIGHTING_INITIAL;
445 
446 
447 	gen->parameters_in_sync = false;
448 
449 
450 	gen->do_dequeue_and_play = false;
451 
452 
453 	gen->buffer = NULL;
454 	gen->buffer_n_samples = -1;
455 
456 	gen->oss_version.x = -1;
457 	gen->oss_version.y = -1;
458 	gen->oss_version.z = -1;
459 
460 
461 	gen->client.name = (char *) NULL;
462 
463 	gen->tone_slope.len = CW_AUDIO_SLOPE_LEN;
464 	gen->tone_slope.shape = CW_TONE_SLOPE_SHAPE_RAISED_COSINE;
465 	gen->tone_slope.amplitudes = NULL;
466 	gen->tone_slope.n_amplitudes = 0;
467 
468 #ifdef LIBCW_WITH_PULSEAUDIO
469 	gen->pa_data.s = NULL;
470 
471 	gen->pa_data.ba.prebuf    = (uint32_t) -1;
472 	gen->pa_data.ba.tlength   = (uint32_t) -1;
473 	gen->pa_data.ba.minreq    = (uint32_t) -1;
474 	gen->pa_data.ba.maxlength = (uint32_t) -1;
475 	gen->pa_data.ba.fragsize  = (uint32_t) -1;
476 #endif
477 
478 	gen->open_device = NULL;
479 	gen->close_device = NULL;
480 	gen->write = NULL;
481 
482 	pthread_attr_init(&gen->thread.attr);
483 	/* Thread must be joinable in order to make a safe call to
484 	   pthread_kill(thread_id, 0). pthreads are joinable by
485 	   default, but I take this explicit call as a good
486 	   opportunity to make this comment. */
487 	pthread_attr_setdetachstate(&gen->thread.attr, PTHREAD_CREATE_JOINABLE);
488 	gen->thread.running = false;
489 
490 
491 	gen->dot_len = 0;
492 	gen->dash_len = 0;
493 	gen->eom_space_len = 0;
494 	gen->eoc_space_len = 0;
495 	gen->eow_space_len = 0;
496 
497 	gen->additional_space_len = 0;
498 	gen->adjustment_space_len = 0;
499 
500 
501 	gen->quantum_len = CW_AUDIO_QUANTUM_LEN_INITIAL;
502 
503 
504 	gen->buffer_sub_start = 0;
505 	gen->buffer_sub_stop  = 0;
506 
507 
508 	gen->key = (cw_key_t *) NULL;
509 
510 
511 	int rv = cw_gen_new_open_internal(gen, audio_system, device);
512 	if (rv == CW_FAILURE) {
513 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_SOUND_SYSTEM, CW_DEBUG_ERROR,
514 			      "libcw: failed to open audio device for audio system '%s' and device '%s'", cw_get_audio_system_label(audio_system), device);
515 		cw_gen_delete_internal(&gen);
516 		return (cw_gen_t *) NULL;
517 	}
518 
519 	if (audio_system == CW_AUDIO_NULL
520 	    || audio_system == CW_AUDIO_CONSOLE) {
521 
522 		; /* the two types of audio output don't require audio buffer */
523 	} else {
524 		gen->buffer = (cw_sample_t *) malloc(gen->buffer_n_samples * sizeof (cw_sample_t));
525 		if (!gen->buffer) {
526 			cw_debug_msg ((&cw_debug_object), CW_DEBUG_STDLIB, CW_DEBUG_ERROR,
527 				      "libcw: malloc()");
528 			cw_gen_delete_internal(&gen);
529 			return (cw_gen_t *) NULL;
530 		}
531 	}
532 
533 	/* Set slope that late, because it uses value of sample rate.
534 	   The sample rate value is set in
535 	   cw_gen_new_open_internal(). */
536 	rv = cw_generator_set_tone_slope(gen, CW_TONE_SLOPE_SHAPE_RAISED_COSINE, CW_AUDIO_SLOPE_LEN);
537 	if (rv == CW_FAILURE) {
538 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_ERROR,
539 			      "libcw: failed to set slope");
540 		cw_gen_delete_internal(&gen);
541 		return (cw_gen_t *) NULL;
542 	}
543 
544 	cw_sigalrm_install_top_level_handler_internal();
545 
546 	return gen;
547 }
548 
549 
550 
551 
552 
553 /**
554    \brief Delete a generator
555 
556    testedin::test_cw_gen_new_delete_internal()
557 */
cw_gen_delete_internal(cw_gen_t ** gen)558 void cw_gen_delete_internal(cw_gen_t **gen)
559 {
560 	cw_assert (gen, "generator is NULL");
561 
562 	if (!*gen) {
563 		return;
564 	}
565 
566 	if ((*gen)->do_dequeue_and_play) {
567 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_DEBUG,
568 			      "libcw: you forgot to call cw_generator_stop()");
569 		cw_gen_stop_internal(*gen);
570 	}
571 
572 	/* Wait for "write" thread to end accessing output
573 	   file descriptor. I have come up with value 500
574 	   after doing some experiments.
575 
576 	   FIXME: magic number. I think that we can come up
577 	   with algorithm for calculating the value. */
578 	usleep(500);
579 
580 	free((*gen)->audio_device);
581 	(*gen)->audio_device = NULL;
582 
583 	free((*gen)->buffer);
584 	(*gen)->buffer = NULL;
585 
586 	if ((*gen)->close_device) {
587 		(*gen)->close_device(*gen);
588 	} else {
589 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_DEBUG, "libcw: WARNING: NULL function pointer, something went wrong");
590 	}
591 
592 	pthread_attr_destroy(&((*gen)->thread.attr));
593 
594 	free((*gen)->client.name);
595 	(*gen)->client.name = NULL;
596 
597 	free((*gen)->tone_slope.amplitudes);
598 	(*gen)->tone_slope.amplitudes = NULL;
599 
600 	cw_tq_delete_internal(&((*gen)->tq));
601 
602 	(*gen)->audio_system = CW_AUDIO_NONE;
603 
604 	free(*gen);
605 	*gen = NULL;
606 
607 	return;
608 }
609 
610 
611 
612 
613 
614 /**
615    \brief Stop a generator
616 
617    Empty generator's tone queue.
618    Silence generator's audio sink.
619    Stop generator' "dequeue and play" thread function.
620    If the thread does not stop in one second, kill it.
621 
622    You have to use cw_gen_start_internal() if you want to enqueue and
623    play tones with the same generator again.
624 
625    It seems that only silencing of generator's audio sink may fail,
626    and this is when this function may return CW_FAILURE. Otherwise
627    function returns CW_SUCCESS.
628 
629    \return CW_SUCCESS if all four actions completed (successfully)
630    \return CW_FAILURE if any of the four actions failed (see note above)
631 */
cw_gen_stop_internal(cw_gen_t * gen)632 int cw_gen_stop_internal(cw_gen_t *gen)
633 {
634 	if (!gen) {
635 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_WARNING,
636 			      "libcw: called the function for NULL generator");
637 		/* Not really a runtime error, so return
638 		   CW_SUCCESS. */
639 		return CW_SUCCESS;
640 	}
641 
642 	cw_tq_flush_internal(gen->tq);
643 
644 	int rv = cw_gen_silence_internal(gen);
645 	if (rv != CW_SUCCESS) {
646 		return CW_FAILURE;
647 	}
648 
649 	cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_INFO,
650 		      "libcw/gen: gen->do_dequeue_and_play = false");
651 	gen->do_dequeue_and_play = false;
652 
653 	if (!gen->thread.running) {
654 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_INFO, "libcw: EXIT: seems that thread function was not started at all");
655 
656 		/* Don't call pthread_kill() on non-initialized
657 		   thread.id. The generator wasn't even started, so
658 		   let's return CW_SUCCESS. */
659 		return CW_SUCCESS;
660 	}
661 
662 	/* "while (gen->do_dequeue_and_play)" loop in thread function
663 	   may be in a state where dequeue() function returned IDLE
664 	   state, and the loop is waiting for new tone.
665 
666 	   This is to wake up cw_signal_wait_internal() function that
667 	   may be waiting idle for signal in "while ()" loop in thread
668 	   function. */
669 	pthread_kill(gen->thread.id, SIGALRM);
670 
671 	/* This piece of comment was put before code using
672 	   pthread_kill(), and may apply only to that version. But it
673 	   may turn out that it will be valid for code using
674 	   pthread_join() as well, so I'm keeping it for now.
675 
676 	   "
677 	   Sleep a bit to postpone closing a device.  This way we can
678 	   avoid a situation when "do_dequeue_and_play" is set to false
679 	   and device is being closed while a new buffer is being
680 	   prepared, and while write() tries to write this new buffer
681 	   to already closed device.
682 
683 	   Without this sleep(), writei() from ALSA library may
684 	   return "File descriptor in bad state" error - this
685 	   happened when writei() tried to write to closed ALSA
686 	   handle.
687 
688 	   The delay also allows the generator function thread to stop
689 	   generating tone (or for tone queue to get out of CW_TQ_IDLE
690 	   state) and exit before we resort to killing generator
691 	   function thread.
692 	   "
693 	*/
694 
695 
696 #if 0 /* Old code using pthread_kill() instead of pthread_join().
697 	 This code is unused since before 2015-08-30. */
698 
699 	struct timespec req = { .tv_sec = 1, .tv_nsec = 0 };
700 	cw_nanosleep_internal(&req);
701 
702 	/* Check if generator thread is still there.  Remember that
703 	   pthread_kill(id, 0) is unsafe for detached threads: if thread
704 	   has finished, the ID may be reused, and may be invalid at
705 	   this point. */
706 	rv = pthread_kill(gen->thread.id, 0);
707 	if (rv == 0) {
708 		/* thread function didn't return yet; let's help it a bit */
709 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_WARNING, "libcw: EXIT: forcing exit of thread function");
710 		rv = pthread_kill(gen->thread.id, SIGKILL);
711 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_WARNING, "libcw: EXIT: pthread_kill() returns %d/%s", rv, strerror(rv));
712 	} else {
713 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_INFO, "libcw: EXIT: seems that thread function exited voluntarily");
714 	}
715 
716 	gen->thread.running = false;
717 	return CW_SUCCESS;
718 #else
719 
720 
721 
722 #define CW_DEBUG_TIMING_JOIN 1
723 
724 #if CW_DEBUG_TIMING_JOIN   /* Debug code to measure how long it takes to join threads. */
725 	struct timeval before, after;
726 	gettimeofday(&before, NULL);
727 #endif
728 
729 
730 
731 	rv = pthread_join(gen->thread.id, NULL);
732 
733 
734 
735 #if CW_DEBUG_TIMING_JOIN   /* Debug code to measure how long it takes to join threads. */
736 	gettimeofday(&after, NULL);
737 	cw_debug_msg ((&cw_debug_object), CW_DEBUG_GENERATOR, CW_DEBUG_INFO, "libcw/gen: joining thread took %d us", cw_timestamp_compare_internal(&before, &after));
738 #endif
739 
740 
741 
742 	if (rv == 0) {
743 		gen->thread.running = false;
744 		return CW_SUCCESS;
745 	} else {
746 		cw_debug_msg ((&cw_debug_object), CW_DEBUG_GENERATOR, CW_DEBUG_ERROR, "libcw/gen: failed to join threads: \"%s\"", strerror(rv));
747 		return CW_FAILURE;
748 	}
749 #endif
750 }
751 
752 
753 
754 
755 
756 /**
757   \brief Open audio system
758 
759   A wrapper for code trying to open audio device specified by
760   \p audio_system.  Open audio system will be assigned to given
761   generator. Caller can also specify audio device to use instead
762   of a default one.
763 
764   \param gen - freshly created generator
765   \param audio_system - audio system to open and assign to the generator
766   \param device - name of audio device to be used instead of a default one
767 
768   \return CW_SUCCESS on success
769   \return CW_FAILURE otherwise
770 */
cw_gen_new_open_internal(cw_gen_t * gen,int audio_system,const char * device)771 int cw_gen_new_open_internal(cw_gen_t *gen, int audio_system, const char *device)
772 {
773 	/* FIXME: this functionality is partially duplicated in
774 	   src/cwutils/cw_common.c/cw_generator_new_from_config() */
775 
776 	/* This function deliberately checks all possible values of
777 	   audio system name in separate 'if' clauses before it gives
778 	   up and returns CW_FAILURE. PA/OSS/ALSA are combined with
779 	   SOUNDCARD, so I have to check all three of them (because \p
780 	   audio_system may be set to SOUNDCARD). And since I check
781 	   the three in separate 'if' clauses, I can check all other
782 	   values of audio system as well. */
783 
784 	if (audio_system == CW_AUDIO_NULL) {
785 
786 		const char *dev = device ? device : default_audio_devices[CW_AUDIO_NULL];
787 		if (cw_is_null_possible(dev)) {
788 			cw_null_configure(gen, dev);
789 			return gen->open_device(gen);
790 		}
791 	}
792 
793 	if (audio_system == CW_AUDIO_PA
794 	    || audio_system == CW_AUDIO_SOUNDCARD) {
795 
796 		const char *dev = device ? device : default_audio_devices[CW_AUDIO_PA];
797 		if (cw_is_pa_possible(dev)) {
798 			cw_pa_configure(gen, dev);
799 			return gen->open_device(gen);
800 		}
801 	}
802 
803 	if (audio_system == CW_AUDIO_OSS
804 	    || audio_system == CW_AUDIO_SOUNDCARD) {
805 
806 		const char *dev = device ? device : default_audio_devices[CW_AUDIO_OSS];
807 		if (cw_is_oss_possible(dev)) {
808 			cw_oss_configure(gen, dev);
809 			return gen->open_device(gen);
810 		}
811 	}
812 
813 	if (audio_system == CW_AUDIO_ALSA
814 	    || audio_system == CW_AUDIO_SOUNDCARD) {
815 
816 		const char *dev = device ? device : default_audio_devices[CW_AUDIO_ALSA];
817 		if (cw_is_alsa_possible(dev)) {
818 			cw_alsa_configure(gen, dev);
819 			return gen->open_device(gen);
820 		}
821 	}
822 
823 	if (audio_system == CW_AUDIO_CONSOLE) {
824 
825 		const char *dev = device ? device : default_audio_devices[CW_AUDIO_CONSOLE];
826 		if (cw_is_console_possible(dev)) {
827 			cw_console_configure(gen, dev);
828 			return gen->open_device(gen);
829 		}
830 	}
831 
832 	/* there is no next audio system type to try */
833 	return CW_FAILURE;
834 }
835 
836 
837 
838 
839 
840 /**
841    \brief Dequeue tones and push them to audio output
842 
843    Function dequeues tones from tone queue associated with generator
844    and then sends them to preconfigured audio output (soundcard, NULL
845    or console).
846 
847    Function dequeues tones (or waits for new tones in queue) and
848    pushes them to audio output as long as
849    generator->do_dequeue_and_play is true.
850 
851    The generator must be fully configured before calling this
852    function.
853 
854    \param arg - generator (casted to (void *)) to be used for generating tones
855 
856    \return NULL pointer
857 */
cw_gen_dequeue_and_play_internal(void * arg)858 void *cw_gen_dequeue_and_play_internal(void *arg)
859 {
860 	cw_gen_t *gen = (cw_gen_t *) arg;
861 
862 	cw_tone_t tone;
863 	CW_TONE_INIT(&tone, 0, 0, CW_SLOPE_MODE_STANDARD_SLOPES);
864 
865 	while (gen->do_dequeue_and_play) {
866 		int tq_rv = cw_tq_dequeue_internal(gen->tq, &tone);
867 		if (tq_rv == CW_TQ_NDEQUEUED_IDLE) {
868 
869 			/* Tone queue has been totally drained with
870 			   previous call to dequeue(). No point in
871 			   making next iteration of while() and
872 			   calling the function again. So don't call
873 			   it, wait for signal from enqueue() function
874 			   informing that a new tone appeared in tone
875 			   queue. */
876 
877 			/* A SIGALRM signal may also come from
878 			   cw_gen_stop_internal() that gently asks
879 			   this function to stop idling and nicely
880 			   return. */
881 
882 			/* TODO: can we / should we specify on which
883 			   signal exactly we are waiting for? */
884 			cw_signal_wait_internal();
885 			continue;
886 		}
887 
888 
889 		cw_key_ik_increment_timer_internal(gen->key, tone.len);
890 
891 #ifdef LIBCW_WITH_DEV
892 		cw_debug_ev ((&cw_debug_object_ev), 0, tone.frequency ? CW_DEBUG_EVENT_TONE_HIGH : CW_DEBUG_EVENT_TONE_LOW);
893 #endif
894 
895 		if (gen->audio_system == CW_AUDIO_NULL) {
896 			cw_null_write(gen, &tone);
897 		} else if (gen->audio_system == CW_AUDIO_CONSOLE) {
898 			cw_console_write(gen, &tone);
899 		} else {
900 			cw_gen_write_to_soundcard_internal(gen, &tone, tq_rv);
901 		}
902 
903 		/*
904 		  When sending text from text input, the signal:
905 		   - allows client code to observe moment when state of tone
906 		     queue is "low/critical"; client code then can add more
907 		     characters to the queue; the observation is done using
908 		     cw_wait_for_tone_queue_critical();
909 
910 		   - allows client code to observe any dequeue event
911                      by waiting for signal in cw_wait_for_tone() /
912                      cw_tq_wait_for_tone_internal()
913 		 */
914 		pthread_kill(gen->client.thread_id, SIGALRM);
915 
916 		/* Generator may be used by iambic keyer to measure
917 		   periods of time (lengths of Mark and Space) - this
918 		   is achieved by enqueueing Marks and Spaces by keyer
919 		   in generator.
920 
921 		   At this point the generator has finished generating
922 		   a tone of specified length. A duration of Mark or
923 		   Space has elapsed. Inform iambic keyer that the
924 		   tone it has enqueued has elapsed.
925 
926 		   (Whether iambic keyer has enqueued any tones or
927 		   not, and whether it is waiting for the
928 		   notification, is a different story. We will let the
929 		   iambic keyer function called below to decide what
930 		   to do with the notification. If keyer is in idle
931 		   graph state, it will ignore the notification.)
932 
933 		   Notice that this mechanism is needed only for
934 		   iambic keyer. Inner workings of straight key are
935 		   much more simple, the straight key doesn't need to
936 		   use generator as a timer. */
937 		if (!cw_key_ik_update_graph_state_internal(gen->key)) {
938 			/* just try again, once */
939 			usleep(1000);
940 			cw_key_ik_update_graph_state_internal(gen->key);
941 		}
942 
943 #ifdef LIBCW_WITH_DEV
944 		cw_debug_ev ((&cw_debug_object_ev), 0, tone.frequency ? CW_DEBUG_EVENT_TONE_LOW : CW_DEBUG_EVENT_TONE_HIGH);
945 #endif
946 
947 	} /* while (gen->do_dequeue_and_play) */
948 
949 	cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_INFO,
950 		      "libcw: EXIT: generator stopped (gen->do_dequeue_and_play = %d)", gen->do_dequeue_and_play);
951 
952 	/* Some functions in client thread may be waiting for the last
953 	   SIGALRM from the generator thread to continue/finalize their
954 	   business. Let's send the SIGALRM right before exiting. */
955 
956 	/* This small delay before sending signal turns out to be helpful.
957 
958 	   TODO: this is one of most mysterious comments in this code
959 	   base. What was I thinking? */
960 	struct timespec req = { .tv_sec = 0, .tv_nsec = CW_NSECS_PER_SEC / 2 };
961 	cw_nanosleep_internal(&req);
962 
963 	pthread_kill(gen->client.thread_id, SIGALRM);
964 	gen->thread.running = false;
965 	return NULL;
966 }
967 
968 
969 
970 
971 
972 /**
973    \brief Calculate a fragment of sine wave
974 
975    Calculate a fragment of sine wave, as many samples as can be fitted
976    in generator buffer's subarea.
977 
978    There will be (gen->buffer_sub_stop - gen->buffer_sub_start + 1)
979    samples calculated and put into gen->buffer[], starting from
980    gen->buffer[gen->buffer_sub_start].
981 
982    The function takes into account all state variables from gen,
983    so initial phase of new fragment of sine wave in the buffer matches
984    ending phase of a sine wave generated in previous call.
985 
986    \param gen - generator that generates sine wave
987    \param tone - generated tone
988 
989    \return number of calculated samples
990 */
cw_gen_calculate_sine_wave_internal(cw_gen_t * gen,cw_tone_t * tone)991 int cw_gen_calculate_sine_wave_internal(cw_gen_t *gen, cw_tone_t *tone)
992 {
993 	assert (gen->buffer_sub_stop <= gen->buffer_n_samples);
994 
995 	/* We need two separate iterators to correctly generate sine wave:
996 	    -- i -- for iterating through output buffer (generator
997 	            buffer's subarea), it can travel between buffer
998 	            cells delimited by start and stop (inclusive);
999 	    -- t -- for calculating phase of a sine wave; 't' always has to
1000 	            start from zero for every calculated subarea (i.e. for
1001 		    every call of this function);
1002 
1003 	  Initial/starting phase of generated fragment is always retained
1004 	  in gen->phase_offset, it is the only "memory" of previously
1005 	  calculated fragment of sine wave (to be precise: it stores phase
1006 	  of last sample in previously calculated fragment).
1007 	  Therefore iterator used to calculate phase of sine wave can't have
1008 	  the memory too. Therefore it has to always start from zero for
1009 	  every new fragment of sine wave. Therefore a separate t. */
1010 
1011 	double phase = 0.0;
1012 	int t = 0;
1013 
1014 	for (int i = gen->buffer_sub_start; i <= gen->buffer_sub_stop; i++) {
1015 		phase = (2.0 * M_PI
1016 				* (double) tone->frequency * (double) t
1017 				/ (double) gen->sample_rate)
1018 			+ gen->phase_offset;
1019 		int amplitude = cw_gen_calculate_amplitude_internal(gen, tone);
1020 
1021 		gen->buffer[i] = amplitude * sin(phase);
1022 
1023 		tone->sample_iterator++;
1024 
1025 		t++;
1026 	}
1027 
1028 	phase = (2.0 * M_PI
1029 		 * (double) tone->frequency * (double) t
1030 		 / (double) gen->sample_rate)
1031 		+ gen->phase_offset;
1032 
1033 	/* "phase" is now phase of the first sample in next fragment to be
1034 	   calculated.
1035 	   However, for long fragments this can be a large value, well
1036 	   beyond <0; 2*Pi) range.
1037 	   The value of phase may further accumulate in different
1038 	   calculations, and at some point it may overflow. This would
1039 	   result in an audible click.
1040 
1041 	   Let's bring back the phase from beyond <0; 2*Pi) range into the
1042 	   <0; 2*Pi) range, in other words lets "normalize" it. Or, in yet
1043 	   other words, lets apply modulo operation to the phase.
1044 
1045 	   The normalized phase will be used as a phase offset for next
1046 	   fragment (during next function call). It will be added phase of
1047 	   every sample calculated in next function call. */
1048 
1049 	int n_periods = floor(phase / (2.0 * M_PI));
1050 	gen->phase_offset = phase - n_periods * 2.0 * M_PI;
1051 
1052 	return t;
1053 }
1054 
1055 
1056 
1057 
1058 
1059 /**
1060    \brief Calculate value of a single sample of sine wave
1061 
1062    This function calculates an amplitude (a value) of a single sample
1063    in sine wave PCM data.
1064 
1065    Actually "calculation" is a bit too big word. The function is just
1066    a three-level-deep decision tree, deciding which of precalculated
1067    values to return. There are no complicated arithmetical
1068    calculations being made each time the function is called, so the
1069    execution time should be pretty small.
1070 
1071    The precalcuated values depend on some factors, so the values
1072    should be re-calculated each time these factors change. See
1073    cw_generator_set_tone_slope() for list of these factors.
1074 
1075    A generator stores some of information needed to get an amplitude
1076    of every sample in a sine wave - this is why we have \p gen.  If
1077    tone's slopes are non-rectangular, the length of slopes is defined
1078    in generator. If a tone is non-silent, the volume is also defined
1079    in generator.
1080 
1081    However, decision tree for getting the amplitude also depends on
1082    some parameters that are strictly bound to tone, such as what is
1083    the shape of slopes for a given tone - this is why we have \p tone.
1084    The \p also stores iterator of samples - this is how we know for
1085    which sample to calculate the amplitude.
1086 
1087    \param gen - generator used to generate a sine wave
1088    \param tone - tone being generated
1089 
1090    \return value of a sample of sine wave, a non-negative number
1091 */
cw_gen_calculate_amplitude_internal(cw_gen_t * gen,cw_tone_t * tone)1092 int cw_gen_calculate_amplitude_internal(cw_gen_t *gen, cw_tone_t *tone)
1093 {
1094 #if 0
1095 	int amplitude = 0;
1096 	/* Blunt algorithm for calculating amplitude;
1097 	   for debug purposes only. */
1098 	if (tone->frequency) {
1099 		amplitude = gen->volume_abs;
1100 	} else {
1101 		amplitude = 0;
1102 	}
1103 
1104 	return amplitude;
1105 #else
1106 
1107 	if (tone->frequency <= 0) {
1108 		return 0;
1109 	}
1110 
1111 
1112 	int amplitude = 0;
1113 
1114 	/* Every tone, regardless of slope mode (CW_SLOPE_MODE_*), has
1115 	   three components. It has rising slope + plateau + falling
1116 	   slope.
1117 
1118 	   There can be four variants of rising and falling slope
1119 	   length, just as there are four CW_SLOPE_MODE_* values.
1120 
1121 	   There can be also tones with zero-length plateau, and there
1122 	   can be also tones with zero-length slopes. */
1123 
1124 	if (tone->sample_iterator < tone->rising_slope_n_samples) {
1125 		/* Beginning of tone, rising slope. */
1126 		int i = tone->sample_iterator;
1127 		amplitude = gen->tone_slope.amplitudes[i];
1128 		assert (amplitude >= 0);
1129 
1130 	} else if (tone->sample_iterator >= tone->rising_slope_n_samples
1131 		   && tone->sample_iterator < tone->n_samples - tone->falling_slope_n_samples) {
1132 
1133 		/* Middle of tone, plateau, constant amplitude. */
1134 		amplitude = gen->volume_abs;
1135 		assert (amplitude >= 0);
1136 
1137 	} else if (tone->sample_iterator >= tone->n_samples - tone->falling_slope_n_samples) {
1138 		/* Falling slope. */
1139 		int i = tone->n_samples - tone->sample_iterator - 1;
1140 		assert (i >= 0);
1141 		amplitude = gen->tone_slope.amplitudes[i];
1142 		assert (amplitude >= 0);
1143 
1144 	} else {
1145 		cw_assert (0, "->sample_iterator out of bounds:\n"
1146 			   "tone->sample_iterator: %d\n"
1147 			   "tone->n_samples: %"PRId64"\n"
1148 			   "tone->rising_slope_n_samples: %d\n"
1149 			   "tone->falling_slope_n_samples: %d\n",
1150 			   tone->sample_iterator,
1151 			   tone->n_samples,
1152 			   tone->rising_slope_n_samples,
1153 			   tone->falling_slope_n_samples);
1154 	}
1155 
1156 	assert (amplitude >= 0);
1157 	return amplitude;
1158 #endif
1159 }
1160 
1161 
1162 
1163 
1164 
1165 /**
1166    \brief Set parameters of tones generated by generator
1167 
1168    Most of variables related to slope of tones is in tone data type,
1169    but there are still some variables that are generator-specific, as
1170    they are common for all tones.  This function sets two of these
1171    variables.
1172 
1173 
1174    A: If you pass to function conflicting values of \p slope_shape and
1175    \p slope_len, the function will return CW_FAILURE. These
1176    conflicting values are rectangular slope shape and larger than zero
1177    slope length. You just can't have rectangular slopes that have
1178    non-zero length.
1179 
1180 
1181    B: If you pass to function '-1' as value of both \p slope_shape and
1182    \p slope_len, the function won't change any of the related two
1183    generator's parameters.
1184 
1185 
1186    C1: If you pass to function '-1' as value of either \p slope_shape
1187    or \p slope_len, the function will attempt to set only this
1188    generator's parameter that is different than '-1'.
1189 
1190    C2: However, if selected slope shape is rectangular, function will
1191    set generator's slope length to zero, even if value of \p
1192    slope_len is '-1'.
1193 
1194 
1195    D: Notice that the function allows non-rectangular slope shape with
1196    zero length of the slopes. The slopes will be non-rectangular, but
1197    just unusually short.
1198 
1199 
1200    The function should be called every time one of following
1201    parameters change:
1202 
1203    \li shape of slope,
1204    \li length of slope,
1205    \li generator's sample rate,
1206    \li generator's volume.
1207 
1208    There are four supported shapes of slopes:
1209    \li linear (the only one supported by libcw until version 4.1.1),
1210    \li raised cosine (supposedly the most desired shape),
1211    \li sine,
1212    \li rectangular.
1213 
1214    Use CW_TONE_SLOPE_SHAPE_* symbolic names as values of \p slope_shape.
1215 
1216    FIXME: first argument of this public function is gen, but no
1217    function provides access to generator variable.
1218 
1219    \param gen - generator for which to set tone slope parameters
1220    \param slope_shape - shape of slope: linear, raised cosine, sine, rectangular
1221    \param slope_len - length of slope [microseconds]
1222 
1223    \return CW_SUCCESS on success
1224    \return CW_FAILURE on failure
1225 */
cw_generator_set_tone_slope(cw_gen_t * gen,int slope_shape,int slope_len)1226 int cw_generator_set_tone_slope(cw_gen_t *gen, int slope_shape, int slope_len)
1227 {
1228 	assert (gen);
1229 
1230 	/* Handle conflicting values of arguments. */
1231 	if (slope_shape == CW_TONE_SLOPE_SHAPE_RECTANGULAR
1232 	    && slope_len > 0) {
1233 
1234 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_ERROR,
1235 			      "libcw: requested a rectangular slope shape, but also requested slope len > 0");
1236 
1237 		return CW_FAILURE;
1238 	}
1239 
1240 	/* Assign new values from arguments. */
1241 	if (slope_shape != -1) {
1242 		gen->tone_slope.shape = slope_shape;
1243 	}
1244 	if (slope_len != -1) {
1245 		gen->tone_slope.len = slope_len;
1246 	}
1247 
1248 
1249 	/* Override of slope length. */
1250 	if (slope_shape == CW_TONE_SLOPE_SHAPE_RECTANGULAR) {
1251 		gen->tone_slope.len = 0;
1252 	}
1253 
1254 
1255 	int slope_n_samples = ((gen->sample_rate / 100) * gen->tone_slope.len) / 10000;
1256 	cw_assert (slope_n_samples >= 0, "negative slope_n_samples: %d", slope_n_samples);
1257 
1258 
1259 	/* Reallocate the table of slope amplitudes only when necessary.
1260 
1261 	   In practice the function will be called foremost when user
1262 	   changes volume of tone (and then the function may be
1263 	   called several times in a row if volume is changed in
1264 	   steps). In such situation the size of amplitudes table
1265 	   doesn't change. */
1266 
1267 	if (gen->tone_slope.n_amplitudes != slope_n_samples) {
1268 
1269 		 /* Remember that slope_n_samples may be zero. In that
1270 		    case realloc() would equal to free(). We don't
1271 		    want to have NULL ->amplitudes, so don't modify
1272 		    ->amplitudes for zero-length slopes.  Since with
1273 		    zero-length slopes we won't be referring to
1274 		    ->amplitudes[], it is ok that the table will not
1275 		    be up-to-date. */
1276 
1277 		if (slope_n_samples > 0) {
1278 			gen->tone_slope.amplitudes = realloc(gen->tone_slope.amplitudes, sizeof(float) * slope_n_samples);
1279 			if (!gen->tone_slope.amplitudes) {
1280 				cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_ERROR,
1281 					      "libcw: failed to realloc() table of slope amplitudes");
1282 				return CW_FAILURE;
1283 			}
1284 		}
1285 
1286 		gen->tone_slope.n_amplitudes = slope_n_samples;
1287 	}
1288 
1289 	cw_gen_recalculate_slopes_internal(gen);
1290 
1291 	return CW_SUCCESS;
1292 }
1293 
1294 
1295 
1296 
1297 
1298 /**
1299    \brief Recalculate amplitudes of PCM samples that form tone's slopes
1300 
1301    TODO: consider writing unit test code for the function.
1302 
1303    \param gen - generator
1304 */
cw_gen_recalculate_slopes_internal(cw_gen_t * gen)1305 void cw_gen_recalculate_slopes_internal(cw_gen_t *gen)
1306 {
1307 	/* The values in amplitudes[] change from zero to max (at
1308 	   least for any sane slope shape), so naturally they can be
1309 	   used in forming rising slope. However they can be used in
1310 	   forming falling slope as well - just iterate the table from
1311 	   end to beginning. */
1312 	for (int i = 0; i < gen->tone_slope.n_amplitudes; i++) {
1313 
1314 		if (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_LINEAR) {
1315 			gen->tone_slope.amplitudes[i] = 1.0 * gen->volume_abs * i / gen->tone_slope.n_amplitudes;
1316 
1317 		} else if (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_SINE) {
1318 			float radian = i * (M_PI / 2.0) / gen->tone_slope.n_amplitudes;
1319 			gen->tone_slope.amplitudes[i] = sin(radian) * gen->volume_abs;
1320 
1321 		} else if (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_RAISED_COSINE) {
1322 			float radian = i * M_PI / gen->tone_slope.n_amplitudes;
1323 			gen->tone_slope.amplitudes[i] = (1 - ((1 + cos(radian)) / 2)) * gen->volume_abs;
1324 
1325 		} else if (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_RECTANGULAR) {
1326 			/* CW_TONE_SLOPE_SHAPE_RECTANGULAR is covered
1327 			   before entering this "for" loop. */
1328 			cw_assert (0, "we shouldn't be here, calculating rectangular slopes");
1329 
1330 		} else {
1331 			cw_assert (0, "unsupported slope shape %d", gen->tone_slope.shape);
1332 		}
1333 	}
1334 
1335 	return;
1336 }
1337 
1338 
1339 
1340 
1341 
1342 /**
1343    \brief Write tone to soundcard
1344 */
cw_gen_write_to_soundcard_internal(cw_gen_t * gen,cw_tone_t * tone,int queue_rv)1345 int cw_gen_write_to_soundcard_internal(cw_gen_t *gen, cw_tone_t *tone, int queue_rv)
1346 {
1347 	assert (queue_rv != CW_TQ_NDEQUEUED_IDLE);
1348 
1349 	if (queue_rv == CW_TQ_NDEQUEUED_EMPTY) {
1350 		/* All tones have been already dequeued from tone
1351 		   queue.
1352 
1353 		   \p tone does not represent a valid tone to play. At
1354 		   first sight there is no need to write anything to
1355 		   soundcard. But...
1356 
1357 		   It may happen that during previous call to the
1358 		   function there were too few samples in a tone to
1359 		   completely fill a buffer (see #needmoresamples tag
1360 		   below).
1361 
1362 		   We need to fill the buffer until it is full and
1363 		   ready to be sent to audio sink.
1364 
1365 		   Since there are no new tones for which we could
1366 		   generate samples, we need to generate silence
1367 		   samples.
1368 
1369 		   Padding the buffer with silence seems to be a good
1370 		   idea (it will work regardless of value (Mark/Space)
1371 		   of last valid tone). We just need to know how many
1372 		   samples of the silence to produce.
1373 
1374 		   Number of these samples will be stored in
1375 		   samples_to_write. */
1376 
1377 		/* We don't have a valid tone, so let's construct a
1378 		   fake one for purposes of padding. */
1379 
1380 		/* Required length of padding space is from end of
1381 		   last buffer subarea to end of buffer. */
1382 		tone->n_samples = gen->buffer_n_samples - (gen->buffer_sub_stop + 1);;
1383 
1384 		tone->len = 0;         /* This value matters no more, because now we only deal with samples. */
1385 		tone->frequency = 0;   /* This fake tone is a piece of silence. */
1386 
1387 		/* The silence tone used for padding doesn't require
1388 		   any slopes. A slope falling to silence has been
1389 		   already provided by last non-fake and non-silent
1390 		   tone. */
1391 		tone->slope_mode = CW_SLOPE_MODE_NO_SLOPES;
1392 		tone->rising_slope_n_samples = 0;
1393 		tone->falling_slope_n_samples = 0;
1394 
1395 		tone->sample_iterator = 0;
1396 
1397 		//fprintf(stderr, "++++ length of padding silence = %d [samples]\n", tone->n_samples);
1398 
1399 	} else { /* tq_rv == CW_TQ_DEQUEUED */
1400 
1401 		/* Recalculate tone parameters from microseconds into
1402 		   samples. After this point the samples will be all
1403 		   that matters. */
1404 
1405 		/* 100 * 10000 = 1.000.000 usecs per second. */
1406 		tone->n_samples = gen->sample_rate / 100;
1407 		tone->n_samples *= tone->len;
1408 		tone->n_samples /= 10000;
1409 
1410 		//fprintf(stderr, "++++ length of regular tone = %d [samples]\n", tone->n_samples);
1411 
1412 		/* Length of a single slope (rising or falling). */
1413 		int slope_n_samples= gen->sample_rate / 100;
1414 		slope_n_samples *= gen->tone_slope.len;
1415 		slope_n_samples /= 10000;
1416 
1417 		if (tone->slope_mode == CW_SLOPE_MODE_RISING_SLOPE) {
1418 			tone->rising_slope_n_samples = slope_n_samples;
1419 			tone->falling_slope_n_samples = 0;
1420 
1421 		} else if (tone->slope_mode == CW_SLOPE_MODE_FALLING_SLOPE) {
1422 			tone->rising_slope_n_samples = 0;
1423 			tone->falling_slope_n_samples = slope_n_samples;
1424 
1425 		} else if (tone->slope_mode == CW_SLOPE_MODE_STANDARD_SLOPES) {
1426 			tone->rising_slope_n_samples = slope_n_samples;
1427 			tone->falling_slope_n_samples = slope_n_samples;
1428 
1429 		} else if (tone->slope_mode == CW_SLOPE_MODE_NO_SLOPES) {
1430 			tone->rising_slope_n_samples = 0;
1431 			tone->falling_slope_n_samples = 0;
1432 
1433 		} else {
1434 			cw_assert (0, "unknown tone slope mode %d", tone->slope_mode);
1435 		}
1436 
1437 		tone->sample_iterator = 0;
1438 	}
1439 
1440 
1441 	/* Total number of samples to write in a loop below. */
1442 	int64_t samples_to_write = tone->n_samples;
1443 
1444 #if 0
1445 	fprintf(stderr, "++++ entering loop, tone->frequency = %d, buffer->n_samples = %d, tone->n_samples = %d, samples_to_write = %d\n",
1446 		tone->frequency, gen->buffer_n_samples, tone->n_samples, samples_to_write);
1447 	fprintf(stderr, "++++ entering loop, expected ~%f loops\n", 1.0 * samples_to_write / gen->buffer_n_samples);
1448 	int debug_loop = 0;
1449 #endif
1450 
1451 
1452 	// cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_DEBUG, "libcw: %lld samples, %d us, %d Hz", tone->n_samples, tone->len, gen->frequency);
1453 	while (samples_to_write > 0) {
1454 
1455 		int64_t free_space = gen->buffer_n_samples - gen->buffer_sub_start;
1456 		if (samples_to_write > free_space) {
1457 			/* There will be some tone samples left for
1458 			   next iteration of this loop.  But this
1459 			   buffer will be ready to be pushed to audio
1460 			   sink. */
1461 			gen->buffer_sub_stop = gen->buffer_n_samples - 1;
1462 		} else if (samples_to_write == free_space) {
1463 			/* How nice, end of tone samples aligns with
1464 			   end of buffer (last sample of tone will be
1465 			   placed in last cell of buffer).
1466 
1467 			   But the result is the same - a full buffer
1468 			   ready to be pushed to audio sink. */
1469 			gen->buffer_sub_stop = gen->buffer_n_samples - 1;
1470 		} else {
1471 			/* There will be too few samples to fill a
1472 			   buffer. We can't send an unready buffer to
1473 			   audio sink. We will have to somehow pad the
1474 			   buffer. */
1475 			gen->buffer_sub_stop = gen->buffer_sub_start + samples_to_write - 1;
1476 		}
1477 
1478 		/* How many samples of audio buffer's subarea will be
1479 		   calculated in a given cycle of "calculate sine
1480 		   wave" code? */
1481 		int buffer_sub_n_samples = gen->buffer_sub_stop - gen->buffer_sub_start + 1;
1482 
1483 
1484 #if 0
1485 		fprintf(stderr, "++++        loop #%d, buffer_sub_n_samples = %d\n", ++debug_loop, buffer_sub_n_samples);
1486 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_DEBUG,
1487 			      "libcw: sub start: %d, sub stop: %d, sub len: %d, to calculate: %d", gen->buffer_sub_start, gen->buffer_sub_stop, buffer_sub_n_samples, samples_to_write);
1488 #endif
1489 
1490 
1491 		int calculated = cw_gen_calculate_sine_wave_internal(gen, tone);
1492 		cw_assert (calculated == buffer_sub_n_samples,
1493 			   "calculated wrong number of samples: %d != %d",
1494 			   calculated, buffer_sub_n_samples);
1495 
1496 
1497 		if (gen->buffer_sub_stop == gen->buffer_n_samples - 1) {
1498 
1499 			/* We have a buffer full of samples. The
1500 			   buffer is ready to be pushed to audio
1501 			   sink. */
1502 			gen->write(gen);
1503 			gen->buffer_sub_start = 0;
1504 			gen->buffer_sub_stop = 0;
1505 #if CW_DEV_RAW_SINK
1506 			cw_dev_debug_raw_sink_write_internal(gen);
1507 #endif
1508 		} else {
1509 			/* #needmoresamples
1510 			   There is still some space left in the
1511 			   buffer, go fetch new tone from tone
1512 			   queue. */
1513 
1514 			gen->buffer_sub_start = gen->buffer_sub_stop + 1;
1515 
1516 			cw_assert (gen->buffer_sub_start <= gen->buffer_n_samples - 1,
1517 				   "sub start out of range: sub start = %d, buffer n samples = %d",
1518 				   gen->buffer_sub_start, gen->buffer_n_samples);
1519 		}
1520 
1521 		samples_to_write -= buffer_sub_n_samples;
1522 
1523 #if 0
1524 		if (samples_to_write < 0) {
1525 			cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_DEBUG, "samples left = %d", samples_to_write);
1526 		}
1527 #endif
1528 
1529 	} /* while (samples_to_write > 0) { */
1530 
1531 	//fprintf(stderr, "++++ left loop, %d loops, samples left = %d\n", debug_loop, (int) samples_to_write);
1532 
1533 	return 0;
1534 }
1535 
1536 
1537 
1538 
1539 
1540 /**
1541    \brief Set sending speed of generator
1542 
1543    See libcw.h/CW_SPEED_{INITIAL|MIN|MAX} for initial/minimal/maximal value
1544    of send speed.
1545 
1546    errno is set to EINVAL if \p new_value is out of range.
1547 
1548    testedin::test_parameter_ranges()
1549 
1550    \param gen - generator for which to set the speed
1551    \param new_value - new value of send speed to be assigned to generator
1552 
1553    \return CW_SUCCESS on success
1554    \return CW_FAILURE on failure
1555 */
cw_gen_set_speed_internal(cw_gen_t * gen,int new_value)1556 int cw_gen_set_speed_internal(cw_gen_t *gen, int new_value)
1557 {
1558 	if (new_value < CW_SPEED_MIN || new_value > CW_SPEED_MAX) {
1559 		errno = EINVAL;
1560 		return CW_FAILURE;
1561 	}
1562 
1563 	if (new_value != gen->send_speed) {
1564 		gen->send_speed = new_value;
1565 
1566 		/* Changes of send speed require resynchronization. */
1567 		gen->parameters_in_sync = false;
1568 		cw_gen_sync_parameters_internal(gen);
1569 	}
1570 
1571 	return CW_SUCCESS;
1572 }
1573 
1574 
1575 
1576 
1577 
1578 /**
1579    \brief Set frequency of generator
1580 
1581    Set frequency of sound wave generated by generator.
1582    The frequency must be within limits marked by CW_FREQUENCY_MIN
1583    and CW_FREQUENCY_MAX.
1584 
1585    See libcw.h/CW_FREQUENCY_{INITIAL|MIN|MAX} for initial/minimal/maximal
1586    value of frequency.
1587 
1588    errno is set to EINVAL if \p new_value is out of range.
1589 
1590    \param gen - generator for which to set new frequency
1591    \param new_value - new value of frequency to be assigned to generator
1592 
1593    \return CW_SUCCESS on success
1594    \return CW_FAILURE on failure
1595 */
cw_gen_set_frequency_internal(cw_gen_t * gen,int new_value)1596 int cw_gen_set_frequency_internal(cw_gen_t *gen, int new_value)
1597 {
1598 	if (new_value < CW_FREQUENCY_MIN || new_value > CW_FREQUENCY_MAX) {
1599 		errno = EINVAL;
1600 		return CW_FAILURE;
1601 	} else {
1602 		gen->frequency = new_value;
1603 		return CW_SUCCESS;
1604 	}
1605 }
1606 
1607 
1608 
1609 
1610 
1611 /**
1612    \brief Set volume of generator
1613 
1614    Set volume of sound wave generated by generator.
1615    The volume must be within limits marked by CW_VOLUME_MIN and CW_VOLUME_MAX.
1616 
1617    Note that volume settings are not fully possible for the console speaker.
1618    In this case, volume settings greater than zero indicate console speaker
1619    sound is on, and setting volume to zero will turn off console speaker
1620    sound.
1621 
1622    See libcw.h/CW_VOLUME_{INITIAL|MIN|MAX} for initial/minimal/maximal
1623    value of volume.
1624    errno is set to EINVAL if \p new_value is out of range.
1625 
1626    \param gen - generator for which to set a volume level
1627    \param new_value - new value of volume to be assigned to generator
1628 
1629    \return CW_SUCCESS on success
1630    \return CW_FAILURE on failure
1631 */
cw_gen_set_volume_internal(cw_gen_t * gen,int new_value)1632 int cw_gen_set_volume_internal(cw_gen_t *gen, int new_value)
1633 {
1634 	if (new_value < CW_VOLUME_MIN || new_value > CW_VOLUME_MAX) {
1635 		errno = EINVAL;
1636 		return CW_FAILURE;
1637 	} else {
1638 		gen->volume_percent = new_value;
1639 		gen->volume_abs = (gen->volume_percent * CW_AUDIO_VOLUME_RANGE) / 100;
1640 
1641 		cw_generator_set_tone_slope(gen, -1, -1);
1642 
1643 		return CW_SUCCESS;
1644 	}
1645 }
1646 
1647 
1648 
1649 
1650 
1651 /**
1652    \brief Set sending gap of generator
1653 
1654    See libcw.h/CW_GAP_{INITIAL|MIN|MAX} for initial/minimal/maximal
1655    value of gap.
1656    errno is set to EINVAL if \p new_value is out of range.
1657 
1658    \param gen - generator for which to set gap
1659    \param new_value - new value of gap to be assigned to generator
1660 
1661    \return CW_SUCCESS on success
1662    \return CW_FAILURE on failure
1663 */
cw_gen_set_gap_internal(cw_gen_t * gen,int new_value)1664 int cw_gen_set_gap_internal(cw_gen_t *gen, int new_value)
1665 {
1666 	if (new_value < CW_GAP_MIN || new_value > CW_GAP_MAX) {
1667 		errno = EINVAL;
1668 		return CW_FAILURE;
1669 	}
1670 
1671 	if (new_value != gen->gap) {
1672 		gen->gap = new_value;
1673 		/* Changes of gap require resynchronization. */
1674 		gen->parameters_in_sync = false;
1675 		cw_gen_sync_parameters_internal(gen);
1676 	}
1677 
1678 	return CW_SUCCESS;
1679 }
1680 
1681 
1682 
1683 
1684 
1685 /**
1686    \brief Set sending weighting for generator
1687 
1688    See libcw.h/CW_WEIGHTING_{INITIAL|MIN|MAX} for initial/minimal/maximal
1689    value of weighting.
1690    errno is set to EINVAL if \p new_value is out of range.
1691 
1692    \param gen - generator for which to set new weighting
1693    \param new_value - new value of weighting to be assigned for generator
1694 
1695    \return CW_SUCCESS on success
1696    \return CW_FAILURE on failure
1697 */
cw_gen_set_weighting_internal(cw_gen_t * gen,int new_value)1698 int cw_gen_set_weighting_internal(cw_gen_t *gen, int new_value)
1699 {
1700 	if (new_value < CW_WEIGHTING_MIN || new_value > CW_WEIGHTING_MAX) {
1701 		errno = EINVAL;
1702 		return CW_FAILURE;
1703 	}
1704 
1705 	if (new_value != gen->weighting) {
1706 		gen->weighting = new_value;
1707 
1708 		/* Changes of weighting require resynchronization. */
1709 		gen->parameters_in_sync = false;
1710 		cw_gen_sync_parameters_internal(gen);
1711 	}
1712 
1713 	return CW_SUCCESS;
1714 }
1715 
1716 
1717 
1718 
1719 
1720 /**
1721    \brief Get sending speed from generator
1722 
1723    \param gen - generator from which to get the parameter
1724 
1725    \return current value of the generator's send speed
1726 */
cw_gen_get_speed_internal(cw_gen_t * gen)1727 int cw_gen_get_speed_internal(cw_gen_t *gen)
1728 {
1729 	return gen->send_speed;
1730 }
1731 
1732 
1733 
1734 
1735 
1736 /**
1737    \brief Get frequency from generator
1738 
1739    Function returns "frequency" parameter of generator,
1740    even if the generator is stopped, or volume of generated sound is zero.
1741 
1742    \param gen - generator from which to get the parameter
1743 
1744    \return current value of generator's frequency
1745 */
cw_gen_get_frequency_internal(cw_gen_t * gen)1746 int cw_gen_get_frequency_internal(cw_gen_t *gen)
1747 {
1748 	return gen->frequency;
1749 }
1750 
1751 
1752 
1753 
1754 
1755 /**
1756    \brief Get sound volume from generator
1757 
1758    Function returns "volume" parameter of generator,
1759    even if the generator is stopped.
1760 
1761    \param gen - generator from which to get the parameter
1762 
1763    \return current value of generator's sound volume
1764 */
cw_gen_get_volume_internal(cw_gen_t * gen)1765 int cw_gen_get_volume_internal(cw_gen_t *gen)
1766 {
1767 	return gen->volume_percent;
1768 }
1769 
1770 
1771 
1772 
1773 
1774 
1775 
1776 
1777 /**
1778    \brief Get sending gap from generator
1779 
1780    \param gen - generator from which to get the parameter
1781 
1782    \return current value of generator's sending gap
1783 */
cw_gen_get_gap_internal(cw_gen_t * gen)1784 int cw_gen_get_gap_internal(cw_gen_t *gen)
1785 {
1786 	return gen->gap;
1787 }
1788 
1789 
1790 
1791 
1792 
1793 /**
1794    \brief Get sending weighting from generator
1795 
1796    \param gen - generator from which to get the parameter
1797 
1798    \return current value of generator's sending weighting
1799 */
cw_gen_get_weighting_internal(cw_gen_t * gen)1800 int cw_gen_get_weighting_internal(cw_gen_t *gen)
1801 {
1802 	return gen->weighting;
1803 }
1804 
1805 
1806 
1807 
1808 
1809 /**
1810    \brief Get timing parameters for sending
1811 
1812    Return the low-level timing parameters calculated from the speed, gap,
1813    tolerance, and weighting set.  Parameter values are returned in
1814    microseconds.
1815 
1816    Use NULL for the pointer argument to any parameter value not required.
1817 
1818    \param gen
1819    \param dot_len
1820    \param dash_len
1821    \param eom_space_len
1822    \param eoc_space_len
1823    \param eow_space_len
1824    \param additional_space_len
1825    \param adjustment_space_len
1826 */
cw_gen_get_send_parameters_internal(cw_gen_t * gen,int * dot_len,int * dash_len,int * eom_space_len,int * eoc_space_len,int * eow_space_len,int * additional_space_len,int * adjustment_space_len)1827 void cw_gen_get_send_parameters_internal(cw_gen_t *gen,
1828 					 int *dot_len,
1829 					 int *dash_len,
1830 					 int *eom_space_len,
1831 					 int *eoc_space_len,
1832 					 int *eow_space_len,
1833 					 int *additional_space_len, int *adjustment_space_len)
1834 {
1835 	cw_gen_sync_parameters_internal(gen);
1836 
1837 	if (dot_len)   *dot_len = gen->dot_len;
1838 	if (dash_len)  *dash_len = gen->dash_len;
1839 
1840 	if (eom_space_len)   *eom_space_len = gen->eom_space_len;
1841 	if (eoc_space_len)   *eoc_space_len = gen->eoc_space_len;
1842 	if (eow_space_len)   *eow_space_len = gen->eow_space_len;
1843 
1844 	if (additional_space_len)    *additional_space_len = gen->additional_space_len;
1845 	if (adjustment_space_len)    *adjustment_space_len = gen->adjustment_space_len;
1846 
1847 	return;
1848 }
1849 
1850 
1851 
1852 
1853 
1854 /**
1855    \brief Play a mark (Dot or Dash)
1856 
1857    Low level primitive to play a tone for mark of the given type, followed
1858    by the standard inter-mark space.
1859 
1860    Function sets errno to EINVAL if an argument is invalid, and
1861    returns CW_FAILURE.
1862 
1863    Function also returns CW_FAILURE if adding the element to queue of
1864    tones failed.
1865 
1866    \param gen - generator to be used to play a mark and inter-mark space
1867    \param mark - mark to send: Dot (CW_DOT_REPRESENTATION) or Dash (CW_DASH_REPRESENTATION)
1868 
1869    \return CW_FAILURE on failure
1870    \return CW_SUCCESS on success
1871 */
cw_gen_play_mark_internal(cw_gen_t * gen,char mark)1872 int cw_gen_play_mark_internal(cw_gen_t *gen, char mark)
1873 {
1874 	int status;
1875 
1876 	/* Synchronize low-level timings if required. */
1877 	cw_gen_sync_parameters_internal(gen);
1878 	/* TODO: do we need to synchronize here receiver as well? */
1879 
1880 	/* Send either a dot or a dash mark, depending on representation. */
1881 	if (mark == CW_DOT_REPRESENTATION) {
1882 		cw_tone_t tone;
1883 		CW_TONE_INIT(&tone, gen->frequency, gen->dot_len, CW_SLOPE_MODE_STANDARD_SLOPES);
1884 		status = cw_tq_enqueue_internal(gen->tq, &tone);
1885 	} else if (mark == CW_DASH_REPRESENTATION) {
1886 		cw_tone_t tone;
1887 		CW_TONE_INIT(&tone, gen->frequency, gen->dash_len, CW_SLOPE_MODE_STANDARD_SLOPES);
1888 		status = cw_tq_enqueue_internal(gen->tq, &tone);
1889 	} else {
1890 		errno = EINVAL;
1891 		status = CW_FAILURE;
1892 	}
1893 
1894 	if (!status) {
1895 		return CW_FAILURE;
1896 	}
1897 
1898 	/* Send the inter-mark space. */
1899 	cw_tone_t tone;
1900 	CW_TONE_INIT(&tone, 0, gen->eom_space_len, CW_SLOPE_MODE_NO_SLOPES);
1901 	if (!cw_tq_enqueue_internal(gen->tq, &tone)) {
1902 		return CW_FAILURE;
1903 	} else {
1904 		return CW_SUCCESS;
1905 	}
1906 }
1907 
1908 
1909 
1910 
1911 
1912 /**
1913    \brief Play end-of-character space
1914 
1915    The function plays space of length 2 Units. The function is
1916    intended to be used after inter-mark space has already been played.
1917 
1918    In such situation standard inter-mark space (one Unit) and
1919    end-of-character space (two Units) form a full standard
1920    end-of-character space (three Units).
1921 
1922    Inter-character adjustment space is added at the end.
1923 
1924    \param gen
1925 
1926    \return CW_SUCCESS on success
1927    \return CW_FAILURE on failure
1928 */
cw_gen_play_eoc_space_internal(cw_gen_t * gen)1929 int cw_gen_play_eoc_space_internal(cw_gen_t *gen)
1930 {
1931 	/* Synchronize low-level timing parameters. */
1932 	cw_gen_sync_parameters_internal(gen);
1933 
1934 	/* Delay for the standard end of character period, plus any
1935 	   additional inter-character gap */
1936 	cw_tone_t tone;
1937 	CW_TONE_INIT(&tone, 0, gen->eoc_space_len + gen->additional_space_len, CW_SLOPE_MODE_NO_SLOPES);
1938 	return cw_tq_enqueue_internal(gen->tq, &tone);
1939 }
1940 
1941 
1942 
1943 
1944 
1945 /**
1946    \brief Play end-of-word space
1947 
1948    The function should be used to play a regular ' ' character.
1949 
1950    The function plays space of length 5 Units. The function is
1951    intended to be used after inter-mark space and end-of-character
1952    space have already been played.
1953 
1954    In such situation standard inter-mark space (one Unit) and
1955    end-of-character space (two Units) and end-of-word space (five
1956    units) form a full standard end-of-word space (seven Units).
1957 
1958    Inter-word adjustment space is added at the end.
1959 
1960    \param gen
1961 
1962    \return CW_SUCCESS on success
1963    \return CW_FAILURE on failure
1964 */
cw_gen_play_eow_space_internal(cw_gen_t * gen)1965 int cw_gen_play_eow_space_internal(cw_gen_t *gen)
1966 {
1967 	/* Synchronize low-level timing parameters. */
1968 	cw_gen_sync_parameters_internal(gen);
1969 
1970 	/* Send silence for the word delay period, plus any adjustment
1971 	   that may be needed at end of word. Make it in two tones,
1972 	   and here is why.
1973 
1974 	   Let's say that 'tone queue low watermark' is one element
1975 	   (i.e. one tone).
1976 
1977 	   In order for tone queue to recognize that a 'low tone
1978 	   queue' callback needs to be called, the level in tq needs
1979 	   to drop from 2 to 1.
1980 
1981 	   Almost every queued character guarantees that there will be
1982 	   at least two tones, e.g for 'E' it is dash + following
1983 	   space. But what about a ' ' character?
1984 
1985 	   If we play ' ' character as single tone, there is only one
1986 	   tone in tone queue, and the tone queue manager can't
1987 	   recognize when the level drops from 2 to 1 (and thus the
1988 	   'low level' callback won't be called).
1989 
1990 	   If we play ' ' character as two separate tones (as we do
1991 	   this in this function), the tone queue manager can
1992 	   recognize level dropping from 2 to 1. Then the passing of
1993 	   critical level can be noticed, and "low level" callback can
1994 	   be called.
1995 
1996 	   BUT: Sometimes the first tone is dequeued before/during the
1997 	   second one is enqueued, and we can't recognize 2->1 event.
1998 
1999 	   So, to be super-sure that there is a recognizable event of
2000 	   passing tone queue level from 2 to 1, we split the eow
2001 	   space into N parts and enqueue them. This way we have N + 1
2002 	   tones per space, and client applications that rely on low
2003 	   level threshold == 1 can correctly work when enqueueing
2004 	   spaces.
2005 
2006 	   At 60 wpm length of gen->eow_space_len is 100000 [us], so
2007 	   it's large enough to safely divide it by small integer
2008 	   value. */
2009 
2010 	int enqueued = 0;
2011 
2012 	cw_tone_t tone;
2013 #if 0
2014 	/* This section is incorrect. Enable this section only for
2015 	   tests.  This section "implements" a bug that was present in
2016 	   libcw until version 6.4.1 and that is now tested by
2017 	   src/libcw/tests/libcw_test_tq_short_space.c */
2018 	int n = 1; /* No division. Old situation causing an error in
2019 		      client applications. */
2020 #else
2021 	int n = 2; /* "small integer value" - used to have more tones per eow space. */
2022 #endif
2023 	CW_TONE_INIT(&tone, 0, gen->eow_space_len / n, CW_SLOPE_MODE_NO_SLOPES);
2024 	for (int i = 0; i < n; i++) {
2025 		int rv = cw_tq_enqueue_internal(gen->tq, &tone);
2026 		if (rv) {
2027 			enqueued++;
2028 		} else {
2029 			return CW_FAILURE;
2030 		}
2031 	}
2032 
2033 	CW_TONE_INIT(&tone, 0, gen->adjustment_space_len, CW_SLOPE_MODE_NO_SLOPES);
2034 	int rv = cw_tq_enqueue_internal(gen->tq, &tone);
2035 	if (rv) {
2036 		enqueued++;
2037 	} else {
2038 		return CW_FAILURE;
2039 	}
2040 
2041 	cw_debug_msg ((&cw_debug_object), CW_DEBUG_GENERATOR, CW_DEBUG_DEBUG,
2042 		      "libcw: enqueued %d tones per eow space, tq len = %d",
2043 		      enqueued, cw_tq_length_internal(gen->tq));
2044 
2045 	return CW_SUCCESS;
2046 }
2047 
2048 
2049 
2050 
2051 
2052 /**
2053    \brief Play the given representation
2054 
2055    Function plays given \p representation using given \p
2056    generator. Every mark from the \p representation is followed by a
2057    standard inter-mark space.
2058 
2059    If \p partial is false, the representation is treated as a complete
2060    (non-partial) data, and a standard end-of-character space is played
2061    at the end (in addition to last inter-mark space). Total length of
2062    space at the end (inter-mark space + end-of-character space) is ~3
2063    Units.
2064 
2065    If \p partial is true, the standard end-of-character space is not
2066    appended. However, the standard inter-mark space is played at the
2067    end.
2068 
2069    Function sets errno to EAGAIN if there is not enough space in tone
2070    queue to enqueue \p representation.
2071 
2072    Function validates \p representation using
2073    cw_representation_is_valid().  Function sets errno to EINVAL if \p
2074    representation is not valid.
2075 
2076    \param gen - generator used to play the representation
2077    \param representation - representation to play
2078    \param partial
2079 
2080    \return CW_FAILURE on failure
2081    \return CW_SUCCESS on success
2082 */
cw_gen_play_representation_internal(cw_gen_t * gen,const char * representation,bool partial)2083 int cw_gen_play_representation_internal(cw_gen_t *gen, const char *representation, bool partial)
2084 {
2085 	if (!cw_representation_is_valid(representation)) {
2086 		errno = EINVAL;
2087 		return CW_FAILURE;
2088 	}
2089 
2090 	/* Before we let this representation loose on tone generation,
2091 	   we'd really like to know that all of its tones will get queued
2092 	   up successfully.  The right way to do this is to calculate the
2093 	   number of tones in our representation, then check that the space
2094 	   exists in the tone queue. However, since the queue is comfortably
2095 	   long, we can get away with just looking for a high water mark.  */
2096 	if (cw_tq_length_internal(gen->tq) >= gen->tq->high_water_mark) {
2097 		errno = EAGAIN;
2098 		return CW_FAILURE;
2099 	}
2100 
2101 	/* Play the marks. Every mark is followed by end-of-mark
2102 	   space. */
2103 	for (int i = 0; representation[i] != '\0'; i++) {
2104 		if (!cw_gen_play_mark_internal(gen, representation[i])) {
2105 			return CW_FAILURE;
2106 		}
2107 	}
2108 
2109 	/* Check if we should append end-of-character space at the end
2110 	   (in addition to last end-of-mark space). */
2111 	if (!partial) {
2112 		if (!cw_gen_play_eoc_space_internal(gen)) {
2113 			return CW_FAILURE;
2114 		}
2115 	}
2116 
2117 	return CW_SUCCESS;
2118 }
2119 
2120 
2121 
2122 
2123 
2124 /**
2125    \brief Look up and play a given ASCII character as Morse code
2126 
2127    If \p partial is set, the end-of-character space is not appended
2128    after last mark of Morse code.
2129 
2130    Function sets errno to ENOENT if \p character is not a recognized character.
2131 
2132    \param gen - generator to be used to play character
2133    \param character - character to play
2134    \param partial
2135 
2136    \return CW_SUCCESS on success
2137    \return CW_FAILURE on failure
2138 */
cw_gen_play_valid_character_internal(cw_gen_t * gen,char character,int partial)2139 int cw_gen_play_valid_character_internal(cw_gen_t *gen, char character, int partial)
2140 {
2141 	if (!gen) {
2142 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_GENERATOR, CW_DEBUG_ERROR,
2143 			      "libcw: no generator available");
2144 		return CW_FAILURE;
2145 	}
2146 
2147 	/* ' ' character (i.e. end-of-word space) is a special case. */
2148 	if (character == ' ') {
2149 		return cw_gen_play_eow_space_internal(gen);
2150 	}
2151 
2152 	/* Lookup the character, and play it. */
2153 	const char *representation = cw_character_to_representation_internal(character);
2154 	if (!representation) {
2155 		errno = ENOENT;
2156 		return CW_FAILURE;
2157 	}
2158 
2159 	if (!cw_gen_play_representation_internal(gen, representation, partial)) {
2160 		return CW_FAILURE;
2161 	} else {
2162 		return CW_SUCCESS;
2163 	}
2164 }
2165 
2166 
2167 
2168 
2169 
2170 /**
2171    \brief Look up and play a given ASCII character as Morse
2172 
2173    The end of character delay is appended to the Morse sent.
2174 
2175    On success the function returns CW_SUCCESS.
2176    On failure the function returns CW_FAILURE and sets errno.
2177 
2178    errno is set to ENOENT if the given character \p c is not a valid
2179    Morse character.
2180    errno is set to EBUSY if current audio sink or keying system is
2181    busy.
2182    errno is set to EAGAIN if the generator's tone queue is full, or if
2183    there is insufficient space to queue the tones for the character.
2184 
2185    This routine returns as soon as the character has been successfully
2186    queued for sending; that is, almost immediately.  The actual sending
2187    happens in background processing.  See cw_wait_for_tone() and
2188    cw_wait_for_tone_queue() for ways to check the progress of sending.
2189 
2190    \param gen - generator to play with
2191    \param c - character to play
2192 
2193    \return CW_SUCCESS on success
2194    \return CW_FAILURE on failure
2195 */
cw_gen_play_character_internal(cw_gen_t * gen,char c)2196 int cw_gen_play_character_internal(cw_gen_t *gen, char c)
2197 {
2198 	/* The call to _is_valid() is placed outside of
2199 	   cw_gen_play_valid_character_internal() for performance
2200 	   reasons.
2201 
2202 	   Or to put it another way:
2203 	   cw_gen_play_valid_character_internal() was created to be
2204 	   called in loop for all characters of validated string, so
2205 	   there was no point in validating all characters separately
2206 	   in that function. */
2207 
2208 	if (!cw_character_is_valid(c)) {
2209 		errno = ENOENT;
2210 		return CW_FAILURE;
2211 	} else {
2212 		return cw_gen_play_valid_character_internal(gen, c, false);
2213 	}
2214 }
2215 
2216 
2217 
2218 
2219 
2220 /**
2221    \brief Look up and play a given ASCII character as Morse code
2222 
2223    "partial" means that the "end of character" delay is not appended
2224    to the Morse code sent by the function, to support the formation of
2225    combination characters.
2226 
2227    On success the function returns CW_SUCCESS.
2228    On failure the function returns CW_FAILURE and sets errno.
2229 
2230    errno is set to ENOENT if the given character \p c is not a valid
2231    Morse character.
2232    errno is set to EBUSY if the audio sink or keying system is busy.
2233    errno is set to EAGAIN if the tone queue is full, or if there is
2234    insufficient space to queue the tones for the character.
2235 
2236    This routine queues its arguments for background processing.  See
2237    cw_wait_for_tone() and cw_wait_for_tone_queue() for ways to check
2238    the progress of sending.
2239 
2240    \param gen - generator to use
2241    \param c - character to play
2242 
2243    \return CW_SUCCESS on success
2244    \return CW_FAILURE on failure
2245 */
cw_gen_play_character_parital_internal(cw_gen_t * gen,char c)2246 int cw_gen_play_character_parital_internal(cw_gen_t *gen, char c)
2247 {
2248 	/* The call to _is_valid() is placed outside of
2249 	   cw_gen_play_valid_character_internal() for performance
2250 	   reasons.
2251 
2252 	   Or to put it another way:
2253 	   cw_gen_play_valid_character_internal() was created to be
2254 	   called in loop for all characters of validated string, so
2255 	   there was no point in validating all characters separately
2256 	   in that function. */
2257 
2258 	if (!cw_character_is_valid(c)) {
2259 		errno = ENOENT;
2260 		return CW_FAILURE;
2261 	} else {
2262 		return cw_gen_play_valid_character_internal(gen, c, true);
2263 	}
2264 }
2265 
2266 
2267 
2268 
2269 
2270 /**
2271    \brief Play a given ASCII string in Morse code
2272 
2273    errno is set to ENOENT if any character in the string is not a
2274    valid Morse character.
2275 
2276    errno is set to EBUSY if audio sink or keying system is busy.
2277 
2278    errno is set to EAGAIN if the tone queue is full or if the tone
2279    queue runs out of space part way through queueing the string.
2280    However, an indeterminate number of the characters from the string
2281    will have already been queued.
2282 
2283    For safety, clients can ensure the tone queue is empty before
2284    queueing a string, or use cw_gen_play_character_internal() if they
2285    need finer control.
2286 
2287    This routine queues its arguments for background processing, the
2288    actual sending happens in background processing. See
2289    cw_wait_for_tone() and cw_wait_for_tone_queue() for ways to check
2290    the progress of sending.
2291 
2292    \param gen - generator to use
2293    \param string - string to play
2294 
2295    \return CW_SUCCESS on success
2296    \return CW_FAILURE on failure
2297 */
cw_gen_play_string_internal(cw_gen_t * gen,const char * string)2298 int cw_gen_play_string_internal(cw_gen_t *gen, const char *string)
2299 {
2300 	/* Check the string is composed of sendable characters. */
2301 	if (!cw_string_is_valid(string)) {
2302 		errno = ENOENT;
2303 		return CW_FAILURE;
2304 	}
2305 
2306 	/* Send every character in the string. */
2307 	for (int i = 0; string[i] != '\0'; i++) {
2308 		if (!cw_gen_play_valid_character_internal(gen, string[i], false))
2309 			return CW_FAILURE;
2310 	}
2311 
2312 	return CW_SUCCESS;
2313 }
2314 
2315 
2316 
2317 
2318 
2319 /**
2320   \brief Reset essential sending parameters to their initial values
2321 
2322   \param gen
2323 */
cw_gen_reset_send_parameters_internal(cw_gen_t * gen)2324 void cw_gen_reset_send_parameters_internal(cw_gen_t *gen)
2325 {
2326 	cw_assert (gen, "generator is NULL");
2327 
2328 	gen->send_speed = CW_SPEED_INITIAL;
2329 	gen->frequency = CW_FREQUENCY_INITIAL;
2330 	gen->volume_percent = CW_VOLUME_INITIAL;
2331 	gen->volume_abs = (gen->volume_percent * CW_AUDIO_VOLUME_RANGE) / 100;
2332 	gen->gap = CW_GAP_INITIAL;
2333 	gen->weighting = CW_WEIGHTING_INITIAL;
2334 
2335 	gen->parameters_in_sync = false;
2336 
2337 	return;
2338 
2339 }
2340 
2341 
2342 
2343 
2344 
2345 /**
2346    \brief Synchronize generator's low level timing parameters
2347 
2348    \param gen - generator
2349 */
cw_gen_sync_parameters_internal(cw_gen_t * gen)2350 void cw_gen_sync_parameters_internal(cw_gen_t *gen)
2351 {
2352 	cw_assert (gen, "generator is NULL");
2353 
2354 	/* Do nothing if we are already synchronized. */
2355 	if (gen->parameters_in_sync) {
2356 		return;
2357 	}
2358 
2359 	/* Set the length of a Dot to be a Unit with any weighting
2360 	   adjustment, and the length of a Dash as three Dot lengths.
2361 	   The weighting adjustment is by adding or subtracting a
2362 	   length based on 50 % as a neutral weighting. */
2363 	int unit_length = CW_DOT_CALIBRATION / gen->send_speed;
2364 	int weighting_length = (2 * (gen->weighting - 50) * unit_length) / 100;
2365 	gen->dot_len = unit_length + weighting_length;
2366 	gen->dash_len = 3 * gen->dot_len;
2367 
2368 	/* End-of-mark space length is one Unit, perhaps adjusted.
2369 	   End-of-character space length is three Units total.
2370 	   End-of-word space length is seven Units total.
2371 
2372 	   WARNING: notice how the eoc and eow spaces are
2373 	   calculated. They aren't full 3 units and 7 units. They are
2374 	   2 units (which takes into account preceding eom space
2375 	   length), and 5 units (which takes into account preceding
2376 	   eom *and* eoc space length). So these two lengths are
2377 	   *additional* ones, i.e. in addition to (already existing)
2378 	   eom and/or eoc space.  Whether this is good or bad idea to
2379 	   calculate them like this is a separate topic. Just be aware
2380 	   of this fact.
2381 
2382 	   The end-of-mark length is adjusted by 28/22 times
2383 	   weighting length to keep PARIS calibration correctly
2384 	   timed (PARIS has 22 full units, and 28 empty ones).
2385 	   End-of-mark and end of character delays take
2386 	   weightings into account. */
2387 	gen->eom_space_len = unit_length - (28 * weighting_length) / 22;  /* End-of-mark space, a.k.a. regular inter-mark space. */
2388 	gen->eoc_space_len = 3 * unit_length - gen->eom_space_len;
2389 	gen->eow_space_len = 7 * unit_length - gen->eoc_space_len;
2390 	gen->additional_space_len = gen->gap * unit_length;
2391 
2392 	/* For "Farnsworth", there also needs to be an adjustment
2393 	   delay added to the end of words, otherwise the rhythm is
2394 	   lost on word end.
2395 	   I don't know if there is an "official" value for this,
2396 	   but 2.33 or so times the gap is the correctly scaled
2397 	   value, and seems to sound okay.
2398 
2399 	   Thanks to Michael D. Ivey <ivey@gweezlebur.com> for
2400 	   identifying this in earlier versions of libcw. */
2401 	gen->adjustment_space_len = (7 * gen->additional_space_len) / 3;
2402 
2403 	cw_debug_msg ((&cw_debug_object), CW_DEBUG_PARAMETERS, CW_DEBUG_INFO,
2404 		      "libcw: send usec timings <%d [wpm]>: dot: %d, dash: %d, %d, %d, %d, %d, %d",
2405 		      gen->send_speed, gen->dot_len, gen->dash_len,
2406 		      gen->eom_space_len, gen->eoc_space_len,
2407 		      gen->eow_space_len, gen->additional_space_len, gen->adjustment_space_len);
2408 
2409 	/* Generator parameters are now in sync. */
2410 	gen->parameters_in_sync = true;
2411 
2412 	return;
2413 }
2414 
2415 
2416 
2417 
2418 
2419 /**
2420    Helper function intended to hide details of tone queue and of
2421    enqueueing a tone from cw_key module.
2422 
2423    'key' is a verb here. The function should be called only on "key
2424    down" (begin mark) event from hardware straight key.
2425 
2426    The function is called in very specific context, see cw_key module
2427    for details.
2428 
2429    \param gen - generator
2430 
2431    \return CW_SUCCESS on success
2432    \return CW_FAILURE on failure
2433 */
cw_gen_key_begin_mark_internal(cw_gen_t * gen)2434 int cw_gen_key_begin_mark_internal(cw_gen_t *gen)
2435 {
2436 	/* In case of straight key we don't know at all how long the
2437 	   tone should be (we don't know for how long the key will be
2438 	   closed).
2439 
2440 	   Let's enqueue a beginning of mark (rising slope) +
2441 	   "forever" (constant) tone. The constant tone will be played
2442 	   until function receives CW_KEY_STATE_OPEN key state. */
2443 
2444 	cw_tone_t tone;
2445 	CW_TONE_INIT(&tone, gen->frequency, gen->tone_slope.len, CW_SLOPE_MODE_RISING_SLOPE);
2446 	int rv = cw_tq_enqueue_internal(gen->tq, &tone);
2447 
2448 	if (rv == CW_SUCCESS) {
2449 
2450 		CW_TONE_INIT(&tone, gen->frequency, gen->quantum_len, CW_SLOPE_MODE_NO_SLOPES);
2451 		tone.forever = true;
2452 		rv = cw_tq_enqueue_internal(gen->tq, &tone);
2453 
2454 		cw_debug_msg ((&cw_debug_object_dev), CW_DEBUG_TONE_QUEUE, CW_DEBUG_DEBUG,
2455 			      "libcw: tone queue: len = %"PRIu32"", cw_tq_length_internal(gen->tq));
2456 	}
2457 
2458 	return rv;
2459 }
2460 
2461 
2462 
2463 
2464 
2465 /**
2466    Helper function intended to hide details of tone queue and of
2467    enqueueing a tone from cw_key module.
2468 
2469    'key' is a verb here. The function should be called only on "key
2470    up" (begin space) event from hardware straight key.
2471 
2472    The function is called in very specific context, see cw_key module
2473    for details.
2474 
2475    \param gen - generator
2476 
2477    \return CW_SUCCESS on success
2478    \return CW_FAILURE on failure
2479 */
cw_gen_key_begin_space_internal(cw_gen_t * gen)2480 int cw_gen_key_begin_space_internal(cw_gen_t *gen)
2481 {
2482 	if (gen->audio_system == CW_AUDIO_CONSOLE) {
2483 		/* Play just a bit of silence, just to switch
2484 		   buzzer from playing a sound to being silent. */
2485 		cw_tone_t tone;
2486 		CW_TONE_INIT(&tone, 0, gen->quantum_len, CW_SLOPE_MODE_NO_SLOPES);
2487 		return cw_tq_enqueue_internal(gen->tq, &tone);
2488 	} else {
2489 		/* For soundcards a falling slope with volume from max
2490 		   to zero should be enough, but... */
2491 		cw_tone_t tone;
2492 		CW_TONE_INIT(&tone, gen->frequency, gen->tone_slope.len, CW_SLOPE_MODE_FALLING_SLOPE);
2493 		int rv = cw_tq_enqueue_internal(gen->tq, &tone);
2494 
2495 		if (rv == CW_SUCCESS) {
2496 			/* ... but on some occasions, on some
2497 			   platforms, some sound systems may need to
2498 			   constantly play "silent" tone. These four
2499 			   lines of code are just for them.
2500 
2501 			   It would be better to avoid queueing silent
2502 			   "forever" tone because this increases CPU
2503 			   usage. It would be better to simply not to
2504 			   queue any new tones after "falling slope"
2505 			   tone. Silence after the last falling slope
2506 			   would simply last on itself until there is
2507 			   new tone on queue to play. */
2508 			CW_TONE_INIT(&tone, 0, gen->quantum_len, CW_SLOPE_MODE_NO_SLOPES);
2509 			tone.forever = true;
2510 			rv = cw_tq_enqueue_internal(gen->tq, &tone);
2511 		}
2512 
2513 		return rv;
2514 	}
2515 }
2516 
2517 
2518 
2519 
2520 
2521 /**
2522    Helper function intended to hide details of tone queue and of
2523    enqueueing a tone from cw_key module.
2524 
2525    'key' is a verb here. It indicates, that the function should be
2526    called on hardware key events only. Since we enqueue symbols, we
2527    know that they have limited, specified length. This means that the
2528    function should be called for events from iambic keyer.
2529 
2530    'Pure' means without any end-of-mark spaces.
2531 
2532    The function is called in very specific context, see cw_key module
2533    for details.
2534 
2535    \param gen - generator
2536    \param symbol - symbol to enqueue (Space/Dot/Dash)
2537 
2538    \return CW_SUCCESS on success
2539    \return CW_FAILURE on failure
2540 */
cw_gen_key_pure_symbol_internal(cw_gen_t * gen,char symbol)2541 int cw_gen_key_pure_symbol_internal(cw_gen_t *gen, char symbol)
2542 {
2543 	cw_tone_t tone;
2544 
2545 	if (symbol == CW_DOT_REPRESENTATION) {
2546 		CW_TONE_INIT(&tone, gen->frequency, gen->dot_len, CW_SLOPE_MODE_STANDARD_SLOPES);
2547 
2548 	} else if (symbol == CW_DASH_REPRESENTATION) {
2549 		CW_TONE_INIT(&tone, gen->frequency, gen->dash_len, CW_SLOPE_MODE_STANDARD_SLOPES);
2550 
2551 	} else if (symbol == CW_SYMBOL_SPACE) {
2552 		CW_TONE_INIT(&tone, 0, gen->eom_space_len, CW_SLOPE_MODE_NO_SLOPES);
2553 
2554 	} else {
2555 		cw_assert (0, "unknown key symbol '%d'", symbol);
2556 	}
2557 
2558 	return cw_tq_enqueue_internal(gen->tq, &tone);
2559 }
2560 
2561 
2562 
2563 
2564 
2565 /* *** Unit tests *** */
2566 
2567 
2568 
2569 
2570 
2571 #ifdef LIBCW_UNIT_TESTS
2572 
2573 
2574 #include "libcw_test.h"
2575 
2576 
2577 
2578 
2579 
2580 /**
2581    tests::cw_gen_new_internal()
2582    tests::cw_gen_delete_internal()
2583 */
test_cw_gen_new_delete_internal(void)2584 unsigned int test_cw_gen_new_delete_internal(void)
2585 {
2586 	int p = fprintf(stdout, "libcw/gen: cw_gen_new/start/stop/delete_internal():\n");
2587 	fflush(stdout);
2588 
2589 	/* Arbitrary number of calls to a set of tested functions. */
2590 	int n = 100;
2591 
2592 	/* new() + delete() */
2593 	for (int i = 0; i < n; i++) {
2594 		fprintf(stderr, "libcw/gen: generator test 1/4, loop #%d/%d\n", i, n);
2595 
2596 		cw_gen_t *gen = cw_gen_new_internal(CW_AUDIO_NULL, NULL);
2597 		cw_assert (gen, "failed to initialize generator (loop #%d)", i);
2598 
2599 		/* Try to access some fields in cw_gen_t just to be
2600 		   sure that the gen has been allocated properly. */
2601 		cw_assert (gen->buffer_sub_start == 0, "buffer_sub_start in new generator is not at zero");
2602 		gen->buffer_sub_stop = gen->buffer_sub_start + 10;
2603 		cw_assert (gen->buffer_sub_stop == 10, "buffer_sub_stop didn't store correct new value");
2604 
2605 		cw_assert (gen->client.name == (char *) NULL, "initial value of generator's client name is not NULL");
2606 
2607 		cw_assert (gen->tq, "tone queue is NULL");
2608 
2609 		cw_gen_delete_internal(&gen);
2610 		cw_assert (gen == NULL, "delete() didn't set the pointer to NULL (loop #%d)", i);
2611 	}
2612 
2613 
2614 	n = 5;
2615 
2616 
2617 	/* new() + start() + delete() (skipping stop() on purpose). */
2618 	for (int i = 0; i < n; i++) {
2619 		fprintf(stderr, "libcw/gen: generator test 2/4, loop #%d/%d\n", i, n);
2620 
2621 		cw_gen_t *gen = cw_gen_new_internal(CW_AUDIO_NULL, NULL);
2622 		cw_assert (gen, "failed to initialize generator (loop #%d)", i);
2623 
2624 		int rv = cw_gen_start_internal(gen);
2625 		cw_assert (rv, "failed to start generator (loop #%d)", i);
2626 
2627 		cw_gen_delete_internal(&gen);
2628 		cw_assert (gen == NULL, "delete() didn't set the pointer to NULL (loop #%d)", i);
2629 	}
2630 
2631 
2632 	/* new() + stop() + delete() (skipping start() on purpose). */
2633 	fprintf(stderr, "libcw/gen: generator test 3/4\n");
2634 	for (int i = 0; i < n; i++) {
2635 		cw_gen_t *gen = cw_gen_new_internal(CW_AUDIO_NULL, NULL);
2636 		cw_assert (gen, "failed to initialize generator (loop #%d)", i);
2637 
2638 		int rv = cw_gen_stop_internal(gen);
2639 		cw_assert (rv, "failed to stop generator (loop #%d)", i);
2640 
2641 		cw_gen_delete_internal(&gen);
2642 		cw_assert (gen == NULL, "delete() didn't set the pointer to NULL (loop #%d)", i);
2643 	}
2644 
2645 
2646 	/* Inner loop limit. */
2647 	int m = n;
2648 
2649 
2650 	/* new() + start() + stop() + delete() */
2651 	for (int i = 0; i < n; i++) {
2652 		fprintf(stderr, "libcw/gen: generator test 4/4, loop #%d/%d\n", i, n);
2653 
2654 		cw_gen_t *gen = cw_gen_new_internal(CW_AUDIO_NULL, NULL);
2655 		cw_assert (gen, "failed to initialize generator (loop #%d)", i);
2656 
2657 		for (int j = 0; j < m; j++) {
2658 			int rv = cw_gen_start_internal(gen);
2659 			cw_assert (rv, "failed to start generator (loop #%d-%d)", i, j);
2660 
2661 			rv = cw_gen_stop_internal(gen);
2662 			cw_assert (rv, "failed to stop generator (loop #%d-%d)", i, j);
2663 		}
2664 
2665 		cw_gen_delete_internal(&gen);
2666 		cw_assert (gen == NULL, "delete() didn't set the pointer to NULL (loop #%d)", i);
2667 	}
2668 
2669 
2670 	p = fprintf(stdout, "libcw/gen: cw_gen_new/start/stop/delete_internal():");
2671 	CW_TEST_PRINT_TEST_RESULT(false, p);
2672 	fflush(stdout);
2673 
2674 	return 0;
2675 }
2676 
2677 
2678 
2679 
test_cw_generator_set_tone_slope(void)2680 unsigned int test_cw_generator_set_tone_slope(void)
2681 {
2682 	int p = fprintf(stdout, "libcw/gen: cw_generator_set_tone_slope():");
2683 
2684 	int audio_system = CW_AUDIO_NULL;
2685 
2686 	/* Test 0: test property of newly created generator. */
2687 	{
2688 		cw_gen_t *gen = cw_gen_new_internal(audio_system, NULL);
2689 		cw_assert (gen, "failed to initialize generator in test 0");
2690 
2691 
2692 		cw_assert (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_RAISED_COSINE,
2693 			   "new generator has unexpected initial slope shape %d", gen->tone_slope.shape);
2694 		cw_assert (gen->tone_slope.len == CW_AUDIO_SLOPE_LEN,
2695 			   "new generator has unexpected initial slope length %d", gen->tone_slope.len);
2696 
2697 
2698 		cw_gen_delete_internal(&gen);
2699 	}
2700 
2701 
2702 
2703 	/* Test A: pass conflicting arguments.
2704 
2705 	   "A: If you pass to function conflicting values of \p
2706 	   slope_shape and \p slope_len, the function will return
2707 	   CW_FAILURE. These conflicting values are rectangular slope
2708 	   shape and larger than zero slope length. You just can't
2709 	   have rectangular slopes that have non-zero length." */
2710 	{
2711 		cw_gen_t *gen = cw_gen_new_internal(audio_system, NULL);
2712 		cw_assert (gen, "failed to initialize generator in test A");
2713 
2714 
2715 		int rv = cw_generator_set_tone_slope(gen, CW_TONE_SLOPE_SHAPE_RECTANGULAR, 10);
2716 		cw_assert (!rv, "function accepted conflicting arguments");
2717 
2718 
2719 		cw_gen_delete_internal(&gen);
2720 	}
2721 
2722 
2723 
2724 	/* Test B: pass '-1' as both arguments.
2725 
2726 	   "B: If you pass to function '-1' as value of both \p
2727 	   slope_shape and \p slope_len, the function won't change
2728 	   any of the related two generator's parameters." */
2729 	{
2730 		cw_gen_t *gen = cw_gen_new_internal(audio_system, NULL);
2731 		cw_assert (gen, "failed to initialize generator in test B");
2732 
2733 
2734 		int shape_before = gen->tone_slope.shape;
2735 		int len_before = gen->tone_slope.len;
2736 
2737 		int rv = cw_generator_set_tone_slope(gen, -1, -1);
2738 		cw_assert (rv, "failed to set tone slope");
2739 
2740 		cw_assert (gen->tone_slope.shape == shape_before,
2741 			   "tone slope shape changed from %d to %d", shape_before, gen->tone_slope.shape);
2742 
2743 		cw_assert (gen->tone_slope.len == len_before,
2744 			   "tone slope length changed from %d to %d", len_before, gen->tone_slope.len);
2745 
2746 
2747 		cw_gen_delete_internal(&gen);
2748 	}
2749 
2750 
2751 
2752 	/* Test C1
2753 
2754 	   "C1: If you pass to function '-1' as value of either \p
2755 	   slope_shape or \p slope_len, the function will attempt to
2756 	   set only this generator's parameter that is different than
2757 	   '-1'." */
2758 	{
2759 		cw_gen_t *gen = cw_gen_new_internal(audio_system, NULL);
2760 		cw_assert (gen, "failed to initialize generator in test C1");
2761 
2762 
2763 		/* At the beginning of test these values are
2764 		   generator's initial values.  As test progresses,
2765 		   some other values will be expected after successful
2766 		   calls to tested function. */
2767 		int expected_shape = CW_TONE_SLOPE_SHAPE_RAISED_COSINE;
2768 		int expected_len = CW_AUDIO_SLOPE_LEN;
2769 
2770 
2771 		/* At this point generator should have initial values
2772 		   of its parameters (yes, that's test zero again). */
2773 		cw_assert (gen->tone_slope.shape == expected_shape,
2774 			   "new generator has unexpected initial slope shape %d", gen->tone_slope.shape);
2775 		cw_assert (gen->tone_slope.len == expected_len,
2776 			   "new generator has unexpected initial slope length %d", gen->tone_slope.len);
2777 
2778 
2779 		/* Set only new slope shape. */
2780 		expected_shape = CW_TONE_SLOPE_SHAPE_LINEAR;
2781 		int rv = cw_generator_set_tone_slope(gen, expected_shape, -1);
2782 		cw_assert (rv, "failed to set linear slope shape with unchanged slope length");
2783 
2784 		/* At this point only slope shape should be updated. */
2785 		cw_assert (gen->tone_slope.shape == expected_shape,
2786 			   "failed to set new shape of slope; shape is %d", gen->tone_slope.shape);
2787 		cw_assert (gen->tone_slope.len == expected_len,
2788 			   "failed to preserve slope length; length is %d", gen->tone_slope.len);
2789 
2790 
2791 		/* Set only new slope length. */
2792 		expected_len = 30;
2793 		rv = cw_generator_set_tone_slope(gen, -1, expected_len);
2794 		cw_assert (rv, "failed to set positive slope length with unchanged slope shape");
2795 
2796 		/* At this point only slope length should be updated
2797 		   (compared to previous function call). */
2798 		cw_assert (gen->tone_slope.shape == expected_shape,
2799 			   "failed to preserve shape of slope; shape is %d", gen->tone_slope.shape);
2800 		cw_assert (gen->tone_slope.len == expected_len,
2801 			   "failed to set new slope length; length is %d", gen->tone_slope.len);
2802 
2803 
2804 		/* Set only new slope shape. */
2805 		expected_shape = CW_TONE_SLOPE_SHAPE_SINE;
2806 		rv = cw_generator_set_tone_slope(gen, expected_shape, -1);
2807 		cw_assert (rv, "failed to set new slope shape with unchanged slope length");
2808 
2809 		/* At this point only slope shape should be updated
2810 		   (compared to previous function call). */
2811 		cw_assert (gen->tone_slope.shape == expected_shape,
2812 			   "failed to set new shape of slope; shape is %d", gen->tone_slope.shape);
2813 		cw_assert (gen->tone_slope.len == expected_len,
2814 			   "failed to preserve slope length; length is %d", gen->tone_slope.len);
2815 
2816 
2817 		cw_gen_delete_internal(&gen);
2818 	}
2819 
2820 
2821 
2822 	/* Test C2
2823 
2824 	   "C2: However, if selected slope shape is rectangular,
2825 	   function will set generator's slope length to zero, even if
2826 	   value of \p slope_len is '-1'." */
2827 	{
2828 		cw_gen_t *gen = cw_gen_new_internal(audio_system, NULL);
2829 		cw_assert (gen, "failed to initialize generator in test C2");
2830 
2831 
2832 		/* At the beginning of test these values are
2833 		   generator's initial values.  As test progresses,
2834 		   some other values will be expected after successful
2835 		   calls to tested function. */
2836 		int expected_shape = CW_TONE_SLOPE_SHAPE_RAISED_COSINE;
2837 		int expected_len = CW_AUDIO_SLOPE_LEN;
2838 
2839 
2840 		/* At this point generator should have initial values
2841 		   of its parameters (yes, that's test zero again). */
2842 		cw_assert (gen->tone_slope.shape == expected_shape,
2843 			   "new generator has unexpected initial slope shape %d", gen->tone_slope.shape);
2844 		cw_assert (gen->tone_slope.len == expected_len,
2845 			   "new generator has unexpected initial slope length %d", gen->tone_slope.len);
2846 
2847 
2848 		/* Set only new slope shape. */
2849 		expected_shape = CW_TONE_SLOPE_SHAPE_RECTANGULAR;
2850 		expected_len = 0; /* Even though we won't pass this to function, this is what we expect to get after this call. */
2851 		int rv = cw_generator_set_tone_slope(gen, expected_shape, -1);
2852 		cw_assert (rv, "failed to set rectangular slope shape with unchanged slope length");
2853 
2854 		/* At this point slope shape AND slope length should
2855 		   be updated (slope length is updated only because of
2856 		   requested rectangular slope shape). */
2857 		cw_assert (gen->tone_slope.shape == expected_shape,
2858 			   "failed to set new shape of slope; shape is %d", gen->tone_slope.shape);
2859 		cw_assert (gen->tone_slope.len == expected_len,
2860 			   "failed to get expected slope length; length is %d", gen->tone_slope.len);
2861 
2862 
2863 		cw_gen_delete_internal(&gen);
2864 	}
2865 
2866 
2867 
2868 	/* Test D
2869 
2870 	   "D: Notice that the function allows non-rectangular slope
2871 	   shape with zero length of the slopes. The slopes will be
2872 	   non-rectangular, but just unusually short." */
2873 	{
2874 		cw_gen_t *gen = cw_gen_new_internal(audio_system, NULL);
2875 		cw_assert (gen, "failed to initialize generator in test D");
2876 
2877 
2878 		int rv = cw_generator_set_tone_slope(gen, CW_TONE_SLOPE_SHAPE_LINEAR, 0);
2879 		cw_assert (rv, "failed to set linear slope with zero length");
2880 		cw_assert (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_LINEAR,
2881 			   "failed to set linear slope shape; shape is %d", gen->tone_slope.shape);
2882 		cw_assert (gen->tone_slope.len == 0,
2883 			   "failed to set zero slope length; length is %d", gen->tone_slope.len);
2884 
2885 
2886 		rv = cw_generator_set_tone_slope(gen, CW_TONE_SLOPE_SHAPE_RAISED_COSINE, 0);
2887 		cw_assert (rv, "failed to set raised cosine slope with zero length");
2888 		cw_assert (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_RAISED_COSINE,
2889 			   "failed to set raised cosine slope shape; shape is %d", gen->tone_slope.shape);
2890 		cw_assert (gen->tone_slope.len == 0,
2891 			   "failed to set zero slope length; length is %d", gen->tone_slope.len);
2892 
2893 
2894 		rv = cw_generator_set_tone_slope(gen, CW_TONE_SLOPE_SHAPE_SINE, 0);
2895 		cw_assert (rv, "failed to set sine slope with zero length");
2896 		cw_assert (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_SINE,
2897 			   "failed to set sine slope shape; shape is %d", gen->tone_slope.shape);
2898 		cw_assert (gen->tone_slope.len == 0,
2899 			   "failed to set zero slope length; length is %d", gen->tone_slope.len);
2900 
2901 
2902 		rv = cw_generator_set_tone_slope(gen, CW_TONE_SLOPE_SHAPE_RECTANGULAR, 0);
2903 		cw_assert (rv, "failed to set rectangular slope with zero length");
2904 		cw_assert (gen->tone_slope.shape == CW_TONE_SLOPE_SHAPE_RECTANGULAR,
2905 			   "failed to set rectangular slope shape; shape is %d", gen->tone_slope.shape);
2906 		cw_assert (gen->tone_slope.len == 0,
2907 			   "failed to set zero slope length; length is %d", gen->tone_slope.len);
2908 
2909 
2910 		cw_gen_delete_internal(&gen);
2911 	}
2912 
2913 
2914 	CW_TEST_PRINT_TEST_RESULT(false, p);
2915 
2916 	return 0;
2917 }
2918 
2919 
2920 
2921 
2922 
2923 /* Test some assertions about CW_TONE_SLOPE_SHAPE_*
2924 
2925    Code in this file depends on the fact that these values are
2926    different than -1. I think that ensuring that they are in general
2927    small, non-negative values is a good idea.
2928 
2929    I'm testing these values to be sure that when I get a silly idea to
2930    modify them, the test will catch this modification.
2931 */
test_cw_gen_tone_slope_shape_enums(void)2932 unsigned int test_cw_gen_tone_slope_shape_enums(void)
2933 {
2934 	int p = fprintf(stdout, "libcw/gen: CW_TONE_SLOPE_SHAPE_*:");
2935 
2936 	cw_assert (CW_TONE_SLOPE_SHAPE_LINEAR >= 0,        "CW_TONE_SLOPE_SHAPE_LINEAR is negative: %d",        CW_TONE_SLOPE_SHAPE_LINEAR);
2937 	cw_assert (CW_TONE_SLOPE_SHAPE_RAISED_COSINE >= 0, "CW_TONE_SLOPE_SHAPE_RAISED_COSINE is negative: %d", CW_TONE_SLOPE_SHAPE_RAISED_COSINE);
2938 	cw_assert (CW_TONE_SLOPE_SHAPE_SINE >= 0,          "CW_TONE_SLOPE_SHAPE_SINE is negative: %d",          CW_TONE_SLOPE_SHAPE_SINE);
2939 	cw_assert (CW_TONE_SLOPE_SHAPE_RECTANGULAR >= 0,   "CW_TONE_SLOPE_SHAPE_RECTANGULAR is negative: %d",   CW_TONE_SLOPE_SHAPE_RECTANGULAR);
2940 
2941 	CW_TEST_PRINT_TEST_RESULT(false, p);
2942 
2943 	return 0;
2944 }
2945 
2946 
2947 
2948 
2949 
2950 /* Version of test_cw_gen_forever() to be used in libcw_test_internal
2951    test executable.
2952 
2953    It's not a test of a "forever" function, but of "forever"
2954    functionality.
2955 */
test_cw_gen_forever_internal(void)2956 unsigned int test_cw_gen_forever_internal(void)
2957 {
2958 	int seconds = 2;
2959 	int p = fprintf(stdout, "libcw/gen: forever tone (%d seconds):", seconds);
2960 	fflush(stdout);
2961 
2962 	unsigned int rv = test_cw_gen_forever_sub(2, CW_AUDIO_NULL, (const char *) NULL);
2963 	cw_assert (rv == 0, "\"forever\" test failed");
2964 
2965 	CW_TEST_PRINT_TEST_RESULT(false, p);
2966 
2967 	return 0;
2968 }
2969 
2970 
2971 
2972 
2973 
test_cw_gen_forever_sub(int seconds,int audio_system,const char * audio_device)2974 unsigned int test_cw_gen_forever_sub(int seconds, int audio_system, const char *audio_device)
2975 {
2976 	cw_gen_t *gen = cw_gen_new_internal(audio_system, audio_device);
2977 	cw_assert (gen, "ERROR: failed to create generator\n");
2978 	cw_gen_start_internal(gen);
2979 	sleep(1);
2980 
2981 	cw_tone_t tone;
2982 	/* Just some acceptable values. */
2983 	int len = 100; /* [us] */
2984 	int freq = 500;
2985 
2986 	CW_TONE_INIT(&tone, freq, len, CW_SLOPE_MODE_RISING_SLOPE);
2987 	cw_tq_enqueue_internal(gen->tq, &tone);
2988 
2989 	CW_TONE_INIT(&tone, freq, gen->quantum_len, CW_SLOPE_MODE_NO_SLOPES);
2990 	tone.forever = true;
2991 	int rv = cw_tq_enqueue_internal(gen->tq, &tone);
2992 
2993 #ifdef __FreeBSD__  /* Tested on FreeBSD 10. */
2994 	/* Separate path for FreeBSD because for some reason signals
2995 	   badly interfere with value returned through second arg to
2996 	   nanolseep().  Try to run the section in #else under FreeBSD
2997 	   to see what happens - value returned by nanosleep() through
2998 	   "rem" will be increasing. */
2999 	fprintf(stderr, "enter any character to end \"forever\" tone\n");
3000 	char c;
3001 	scanf("%c", &c);
3002 #else
3003 	struct timespec t;
3004 	cw_usecs_to_timespec_internal(&t, seconds * CW_USECS_PER_SEC);
3005 	cw_nanosleep_internal(&t);
3006 #endif
3007 
3008 	CW_TONE_INIT(&tone, freq, len, CW_SLOPE_MODE_FALLING_SLOPE);
3009 	rv = cw_tq_enqueue_internal(gen->tq, &tone);
3010 	cw_assert (rv, "failed to enqueue last tone");
3011 
3012 	cw_gen_delete_internal(&gen);
3013 
3014 	return 0;
3015 }
3016 
3017 
3018 
3019 
3020 
3021 #endif /* #ifdef LIBCW_UNIT_TESTS */
3022