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