1 /*
2   This file is a part of unixcw project.
3   unixcw project is covered by GNU General Public License.
4 */
5 
6 #ifndef H_LIBCW_GEN
7 #define H_LIBCW_GEN
8 
9 
10 
11 
12 
13 #include "libcw.h"
14 #include "libcw_pa.h"
15 #include "libcw_alsa.h"
16 #include "libcw_tq.h"
17 #include "libcw_key.h"
18 
19 
20 
21 
22 
23 /* Allowed values of cw_tone_t.slope_mode.  This is to decide whether
24    a tone has slopes at all. If there are any slopes in a tone, there
25    can be only rising slope (without falling slope), falling slope
26    (without rising slope), or both slopes (i.e. standard slopes).
27    These values don't tell anything about shape of slopes (unless you
28    consider 'no slopes' a shape ;) ). */
29 #define CW_SLOPE_MODE_STANDARD_SLOPES   20
30 #define CW_SLOPE_MODE_NO_SLOPES         21
31 #define CW_SLOPE_MODE_RISING_SLOPE      22
32 #define CW_SLOPE_MODE_FALLING_SLOPE     23
33 
34 
35 
36 
37 
38 /* Symbolic name for inter-mark space. */
39 enum { CW_SYMBOL_SPACE = ' ' };
40 
41 
42 
43 
44 
45 /* This is used in libcw_gen and libcw_debug. */
46 #ifdef LIBCW_WITH_DEV
47 #define CW_DEV_RAW_SINK           1  /* Create and use /tmp/cw_file.<audio system>.raw file with audio samples written as raw data. */
48 #define CW_DEV_RAW_SINK_MARKERS   0  /* Put markers in raw data saved to raw sink. */
49 #else
50 #define CW_DEV_RAW_SINK           0
51 #define CW_DEV_RAW_SINK_MARKERS   0
52 #endif
53 
54 
55 
56 
57 
58 struct cw_gen_struct {
59 
60 	int  (* open_device)(cw_gen_t *gen);
61 	void (* close_device)(cw_gen_t *gen);
62 	int  (* write)(cw_gen_t *gen);
63 
64 	/* Generator can only generate tones that were first put into
65 	   queue, and then dequeued. Here is a tone queue associated
66 	   with a generator. One tone queue per generator. One
67 	   generator per tone queue.
68 
69 	   The tone queue should be created in generator's
70 	   constructor, and deleted in generator's destructor using
71 	   tone queue's own constructor and destructor functions - see
72 	   cw_tq module for declarations of these functions. */
73 	cw_tone_queue_t *tq;
74 
75 
76 
77 	/* Buffer storing sine wave that is calculated in "calculate sine
78 	   wave" cycles and sent to audio system (OSS, ALSA, PulseAudio).
79 
80 	   The buffer should be always filled with valid data before sending
81 	   it to audio system (to avoid hearing garbage).
82 
83 	   We should also send exactly buffer_n_samples samples to audio
84 	   system, in order to avoid situation when audio system waits for
85 	   filling its buffer too long - this would result in errors and
86 	   probably audible clicks. */
87 	cw_sample_t *buffer;
88 
89 	/* Size of data buffer, in samples.
90 
91 	   The size may be restricted (min,max) by current audio system
92 	   (OSS, ALSA, PulseAudio); the audio system may also accept only
93 	   specific values of the size.
94 
95 	   Audio libraries may provide functions that can be used to query
96 	   for allowed audio buffer sizes.
97 
98 	   The smaller the buffer, the more often you have to call function
99 	   writing data to audio system, which increases CPU usage.
100 
101 	   The larger the buffer, the less responsive an application may
102 	   be to changes of audio data parameters (depending on application
103 	   type). */
104 	int buffer_n_samples;
105 
106 
107 	/* We need two indices to gen->buffer, indicating beginning
108 	   and end of a subarea in the buffer.  The subarea is not
109 	   exactly the same as gen->buffer for variety of reasons:
110 	   - buffer length is almost always smaller than length of a
111 	   Mark or Space (in samples) that we want to produce;
112 	   - moreover, length of a Mark/Space (in samples) is almost
113 	   never an exact multiple of length of a buffer;
114 	   - as a result, a sound representing a Mark/Space may start
115 	   and end anywhere between beginning and end of the buffer;
116 
117 	   A workable solution is to have a subarea of the buffer, a
118 	   window, into which we will write a series of fragments of
119 	   calculated sound.
120 
121 	   "start" and "stop" mark beginning and end of the subarea
122 	   (inclusive: samples indexed by "start" and "stop" are part
123 	   of the subarea).
124 
125 	   The subarea shall not wrap around boundaries of the buffer:
126 	   "stop" shall be no larger than "gen->buffer_n_samples - 1",
127 	   and it shall never be smaller than "start". "start" will be
128 	   somewhere between zero and "stop", inclusive.
129 
130 	   "start" == "stop" is a valid situation - length of subarea
131 	   is then one.
132 
133 	   Very often (in the middle of a long tone), "start" will be
134 	   zero, and "stop" will be "gen->buffer_n_samples - 1".
135 
136 	   Sine wave (sometimes with amplitude = 0) will be calculated
137 	   for subarea's cells (samples) ranging from cell "start"
138 	   to cell "stop", inclusive. */
139 	int buffer_sub_start;
140 	int buffer_sub_stop;
141 
142 
143 	/* Some parameters of tones (and of tones' slopes) are common
144 	   for all tones generated in given time by a generator.
145 	   Therefore the generator should contain this struct.
146 
147 	   Other parameters, such as tone's length or frequency, are
148 	   strictly related to tones - you won't find them here. */
149 	struct {
150 		/* Depending on sample rate, sending speed, and user
151 		   preferences, length of slope of tones generated by
152 		   generator may vary, but once set, it is constant
153 		   for all generated tones (until next change of
154 		   sample rate, sending speed, etc.).
155 
156 		   This is why we have the slope length in generator.
157 
158 		   n_amplitudes declared a bit below in this struct is
159 		   a secondary parameter, derived from ->len. */
160 		int len; /* [us] */
161 
162 		/* Linear/raised cosine/sine/rectangle. */
163 		int shape;
164 
165 		/* Table of amplitudes of every PCM sample of tone's
166 		   slope.
167 
168 		   The values in amplitudes[] change from zero to max
169 		   (at least for any sane slope shape), so naturally
170 		   they can be used in forming rising slope. However
171 		   they can be used in forming falling slope as well -
172 		   just iterate the table from end to beginning. */
173 		float *amplitudes;
174 
175 		/* This is a secondary parameter, derived from
176 		   ->len. n_amplitudes is useful when iterating over
177 		   ->amplitudes[] or reallocing the ->amplitudes[]. */
178 		int n_amplitudes;
179 	} tone_slope;
180 
181 
182 	/* none/null/console/OSS/ALSA/PulseAudio */
183 	int audio_system;
184 
185 	bool audio_device_is_open;
186 
187 	/* Path to console file, or path to OSS soundcard file,
188 	   or ALSA sound device name, or PulseAudio device name
189 	   (it may be unused for PulseAudio) */
190 	char *audio_device;
191 
192 	/* Output file descriptor for audio data (console, OSS). */
193 	int audio_sink;
194 
195 #ifdef LIBCW_WITH_ALSA
196 	/* Data used by ALSA. */
197 	cw_alsa_data_t alsa_data;
198 #endif
199 
200 #ifdef LIBCW_WITH_PULSEAUDIO
201 	/* Data used by PulseAudio. */
202 	cw_pa_data_t pa_data;
203 #endif
204 
205 	struct {
206 		int x;
207 		int y;
208 		int z;
209 	} oss_version;
210 
211 	/* Output file descriptor for debug data (console, OSS, ALSA, PulseAudio). */
212 	int dev_raw_sink;
213 
214 
215 	/* Essential sending parameters. */
216 	int send_speed;     /* [wpm] */
217 	int frequency;      /* The frequency of generated sound. [Hz] */
218 	int volume_percent; /* Level of sound in percents of maximum allowable level. */
219 	int volume_abs;     /* Level of sound in absolute terms; height of PCM samples. */
220 	int gap;            /* Inter-mark gap. [number of dot lengths]. */
221 	int weighting;      /* Dot/dash weighting. */
222 
223 
224 
225 	/* After changing sending speed, gap or weighting, some
226 	   generator's internal parameters need to be
227 	   re-calculated. This is a flag that shows when this needs to
228 	   be done. */
229 	bool parameters_in_sync;
230 
231 
232 	int sample_rate; /* set to the same value of sample rate as
233 			    you have used when configuring sound card */
234 
235 	/* start/stop flag.
236 	   Set to true before running dequeue_and_play thread
237 	   function.
238 	   Set to false to stop generator and return from
239 	   dequeue_and_play thread function. */
240 	bool do_dequeue_and_play;
241 
242 	/* Used to calculate sine wave.
243 	   Phase offset needs to be stored between consecutive calls to
244 	   function calculating consecutive fragments of sine wave. */
245 	double phase_offset;
246 
247 	/* Properties of generator's thread function is that is used
248 	   to generate sine wave and write the wave to audio sink
249 	   (cw_gen_dequeue_and_play_internal()). */
250 	struct {
251 		pthread_t      id;
252 		pthread_attr_t attr;
253 
254 		/* Call to pthread_create(&id, ...) executed and
255 		   succeeded? If not, don't call pthread_kill(). I
256 		   can't check value of thread.id, because pthread_t
257 		   data type is opaque.
258 
259 		   This flag is a bit different than
260 		   cw_gen_t->do_dequeue_and_play.  Setting
261 		   ->do_dequeue_and_play signals intent to run a loop
262 		   deqeueing tones in
263 		   cw_gen_dequeue_and_play_internal().  Setting
264 		   ->thread.running means that thread function
265 		   cw_gen_dequeue_and_play_internal() was launched
266 		   successfully. */
267 		bool running;
268 	} thread;
269 
270 	struct {
271 		/* Main thread, existing from beginning to end of main process run.
272 		   The variable is used to send signals to main app thread. */
273 		pthread_t thread_id;
274 		char *name;
275 	} client;
276 
277 
278 
279 	/* These are basic timing parameters which should be
280 	   recalculated each time client code demands changing some
281 	   higher-level parameter of generator (e.g. changing of
282 	   sending speed). */
283 
284 	/* Watch out for "additional" key word.
285 
286 	   WARNING: notice how the eoc and eow spaces are
287 	   calculated. They aren't full 3 units and 7 units. They are
288 	   2 units (which takes into account preceding eom space
289 	   length), and 5 units (which takes into account preceding
290 	   eom *and* eoc space length). So these two lengths are
291 	   *additional* ones, i.e. in addition to (already existing)
292 	   eom and/or eoc space.  Whether this is good or bad idea to
293 	   calculate them like this is a separate topic. Just be aware
294 	   of this fact.
295 
296 	   Search the word "*additional*" in libcw_gen.c for
297 	   implementation */
298 	int dot_len;              /* Length of a dot. [us] */
299 	int dash_len;             /* Length of a dash. [us] */
300 	int eom_space_len;        /* Length of end-of-mark space (i.e. inter-mark space). [us] */
301 	int eoc_space_len;        /* Length of *additional* end-of-character space. [us] */
302 	int eow_space_len;        /* Length of *additional* end-of-word space. [us] */
303 	int additional_space_len; /* Length of additional space at the end of a character. [us] */
304 	int adjustment_space_len; /* Length of adjustment space at the end of a word. [us] */
305 
306 
307 	/* Shortest length of tone. Right now it's initialized in
308 	   constructor and never changed afterwards, but in future it
309 	   may change - the value may be dynamically modified for
310 	   performance reasons. The longer the quantum length, the
311 	   less often some functions need to be called.
312 
313 	   TODO: do we need a separate cw_gen_t->forever_len field?
314 	   Are there cases where "length of forever tone" != "quantum
315 	   length"? */
316 	int quantum_len;
317 
318 
319 	/* Key that has a generator associated with it.
320 
321 	   Standalone generator will have this set to NULL. But
322 	   generator that is used by a key will have this set to
323 	   non-NULL value with
324 	   cw_key_register_generator_internal(). Remember that the key
325 	   needs to have a generator, not the other way around. */
326 	volatile struct cw_key_struct *key;
327 };
328 
329 
330 
331 
332 /* Basic generator functions. */
333 cw_gen_t *cw_gen_new_internal(int audio_system, const char *device);
334 void      cw_gen_delete_internal(cw_gen_t **gen);
335 int       cw_gen_start_internal(cw_gen_t *gen);
336 int       cw_gen_stop_internal(cw_gen_t *gen);
337 
338 
339 
340 
341 
342 /* Setters of generator's basic parameters. */
343 int cw_gen_set_speed_internal(cw_gen_t *gen, int new_value);
344 int cw_gen_set_frequency_internal(cw_gen_t *gen, int new_value);
345 int cw_gen_set_volume_internal(cw_gen_t *gen, int new_value);
346 int cw_gen_set_gap_internal(cw_gen_t *gen, int new_value);
347 int cw_gen_set_weighting_internal(cw_gen_t *gen, int new_value);
348 
349 
350 
351 
352 /* Getters of generator's basic parameters. */
353 int cw_gen_get_speed_internal(cw_gen_t *gen);
354 int cw_gen_get_frequency_internal(cw_gen_t *gen);
355 int cw_gen_get_volume_internal(cw_gen_t *gen);
356 int cw_gen_get_gap_internal(cw_gen_t *gen);
357 int cw_gen_get_weighting_internal(cw_gen_t *gen);
358 
359 
360 
361 
362 
363 void 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);
364 
365 
366 
367 
368 
369 /* Generator's 'play' primitives. */
370 int cw_gen_play_mark_internal(cw_gen_t *gen, char mark);
371 int cw_gen_play_eoc_space_internal(cw_gen_t *gen);
372 int cw_gen_play_eow_space_internal(cw_gen_t *gen);
373 
374 /* These are also 'play' primitives, but are intended to be used on
375    hardware key events. 'key' is a verb here. */
376 int cw_gen_key_begin_mark_internal(cw_gen_t *gen);
377 int cw_gen_key_begin_space_internal(cw_gen_t *gen);
378 int cw_gen_key_pure_symbol_internal(cw_gen_t *gen, char symbol);
379 
380 
381 
382 
383 
384 int cw_gen_play_representation_internal(cw_gen_t *gen, const char *representation, bool partial);
385 int cw_gen_play_character_internal(cw_gen_t *gen, char c);
386 int cw_gen_play_character_parital_internal(cw_gen_t *gen, char c);
387 int cw_gen_play_string_internal(cw_gen_t *gen, const char *string);
388 
389 
390 
391 int   cw_gen_set_audio_device_internal(cw_gen_t *gen, const char *device);
392 int   cw_gen_silence_internal(cw_gen_t *gen);
393 char *cw_gen_get_audio_system_label_internal(cw_gen_t *gen);
394 
395 void cw_generator_delete_internal(void);
396 
397 void cw_gen_reset_send_parameters_internal(cw_gen_t *gen);
398 void cw_gen_sync_parameters_internal(cw_gen_t *gen);
399 
400 
401 
402 
403 
404 #ifdef LIBCW_UNIT_TESTS
405 
406 unsigned int test_cw_generator_set_tone_slope(void);
407 unsigned int test_cw_gen_tone_slope_shape_enums(void);
408 unsigned int test_cw_gen_new_delete_internal(void);
409 unsigned int test_cw_gen_forever_internal(void);
410 
411 
412 /* This is helper function (performing the real test), used in
413    libcw_test_public and in libcw_test_internal.
414 
415    "forever" feature is not a part of public api, so in theory it
416    shouldn't be tested in libcw_test_public, but the libcw_test_public
417    is able to perform tests with different audio sinks, whereas
418    libcw_test_internal only uses NULL audio sink.
419 
420    So libcw_test_internal does basic tests ("does it work at all?"),
421    and libcw_test_public does full test.
422 */
423 unsigned int test_cw_gen_forever_sub(int seconds, int audio_system, const char *audio_device);
424 
425 #endif /* #ifdef LIBCW_UNIT_TESTS */
426 
427 
428 
429 
430 
431 #endif /* #ifndef H_LIBCW_GEN */
432