libsstvenc
Asynchronous Analogue SSTV encoder
Loading...
Searching...
No Matches
CW encoder and modulator implementation.
Collaboration diagram for CW encoder and modulator implementation.:

Topics

 CW modulator states
 

Data Structures

struct  sstvenc_cw_mod
 
struct  sstvenc_cw_pair
 

Functions

void sstvenc_cw_init (struct sstvenc_cw_mod *const cw, const char *text, double amplitude, double frequency, double dit_period, double slope_period, uint32_t sample_rate, uint8_t time_unit)
 
void sstvenc_cw_compute (struct sstvenc_cw_mod *const cw)
 
size_t sstvenc_cw_fill_buffer (struct sstvenc_cw_mod *const cw, double *buffer, size_t buffer_sz)
 
static const struct sstvenc_cw_pairsstvenc_cw_symbol_match (const char *sym, const struct sstvenc_cw_pair *candidate)
 
static const struct sstvenc_cw_pairsstvenc_cw_symbol_lookup (const char *sym, const struct sstvenc_cw_pair *table, uint8_t len)
 
static const struct sstvenc_cw_pairsstvenc_cw_get_symbol (const char *sym)
 
static void sstvenc_cw_get_next_sym (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_start_mark (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_end_subsym (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_end_symbol (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_handle_state_mark (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_handle_state_ditspace (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_handle_state_dahspace (struct sstvenc_cw_mod *const cw)
 
static void sstvenc_cw_handle_state_done (struct sstvenc_cw_mod *const cw)
 

Variables

static struct sstvenc_cw_pair sstvenc_cw_symbols []
 
static struct sstvenc_cw_pair sstvenc_cw_mbsymbols []
 

Detailed Description

This module implements a morse-code modulator for generating CW IDs as required by some juristictions for computer-generated transmissions.

Operation is pretty simple:

struct sstvenc_cw_mod cw;
&cw, // pass in the context
"HELLO WORLD", // your text to transmit
1.0, // amplitude [0.0, 1.0]
800.0, // frequency in Hz
200, // dit period
5, // rising/falling slope period
48000, // sample rate in Hz
);
while(cw.state != SSTVENC_CW_MOD_STATE_DONE) {
write_to_audio_output(&cw.output);
}
#define SSTVENC_CW_MOD_STATE_DONE
Definition cw.h:91
void sstvenc_cw_compute(struct sstvenc_cw_mod *const cw)
Definition cw.c:507
void sstvenc_cw_init(struct sstvenc_cw_mod *const cw, const char *text, double amplitude, double frequency, double dit_period, double slope_period, uint32_t sample_rate, uint8_t time_unit)
Definition cw.c:312
#define SSTVENC_TS_UNIT_MILLISECONDS
Definition timescale.h:37

The text is assumed to be UTF-8 format using symbols defined in one of two symbol tables:

Any character not in those tables will be ignored by the state machine.


Data Structure Documentation

◆ sstvenc_cw_mod

struct sstvenc_cw_mod

CW state machine context. This structure bundles an oscillator and pulse shaper to generate a morse code waveform from the plain text given.

This should be initialised by calling sstvenc_cw_init. Then, to obtain samples, call sstvenc_cw_compute. Each output sample is then emitted via sstvenc_cw_mod::output.

The state machine's progress can be tracked by observing sstvenc_cw_mod::state. The modulator is finished transmitting when this changes to SSTVENC_CW_MOD_STATE_DONE.

Definition at line 109 of file cw.h.

Collaboration diagram for sstvenc_cw_mod:
Data Fields
uint16_t dit_period

Dit period in samples

struct sstvenc_oscillator osc

Oscillator for the modulator.

double output

Output sample. Call @sstvenc_cw_compute to calculate this, then read the result from here.

uint8_t pos

Position within the current symbol being transmitted.

struct sstvenc_pulseshape ps

Pulse shaper for the modulator.

uint8_t state

Current state machine state

const struct sstvenc_cw_pair * symbol

Current symbol being transmitted

const char * text_string

UTF-8 string to be transmitted. Valid symbols for transmission are given in the tables sstvenc_cw_symbols and sstvenc_cw_mbsymbols.

The non-English Ch character can be emitted using the pseudo prosign <CH> or the equivalent character Ĥ to avoid it getting confused with the C and H symbols. Anything else will be ignored.

During transmission, this pointer will be incremented.

◆ sstvenc_cw_pair

struct sstvenc_cw_pair

Symbol table mapping element. Used to map a symbol to its morse-code representation. It can be considered a key-value pair of strings.

Definition at line 18 of file cw.c.

Collaboration diagram for sstvenc_cw_pair:
Data Fields
const char * key
const char * value

Function Documentation

◆ sstvenc_cw_compute()

void sstvenc_cw_compute ( struct sstvenc_cw_mod *const cw)

Compute the next sample in the state machine. The state machine will be advanced to the next state and a sample written to sstvenc_cw_mod::output.

Definition at line 507 of file cw.c.

507 {
508 switch (cw->state) {
512 break;
515 break;
518 break;
521 break;
523 default:
525 return;
526 }
527}
#define SSTVENC_CW_MOD_STATE_DAHSPACE
Definition cw.h:85
#define SSTVENC_CW_MOD_STATE_INIT
Definition cw.h:64
#define SSTVENC_CW_MOD_STATE_MARK
Definition cw.h:75
#define SSTVENC_CW_MOD_STATE_DITSPACE
Definition cw.h:80
#define SSTVENC_CW_MOD_STATE_NEXT_SYM
Definition cw.h:70
uint8_t state
Definition cw.h:142
static void sstvenc_cw_handle_state_done(struct sstvenc_cw_mod *const cw)
Definition cw.c:501
static void sstvenc_cw_get_next_sym(struct sstvenc_cw_mod *const cw)
Definition cw.c:383
static void sstvenc_cw_handle_state_ditspace(struct sstvenc_cw_mod *const cw)
Definition cw.c:484
static void sstvenc_cw_handle_state_dahspace(struct sstvenc_cw_mod *const cw)
Definition cw.c:493
static void sstvenc_cw_handle_state_mark(struct sstvenc_cw_mod *const cw)
Definition cw.c:454

References sstvenc_cw_get_next_sym(), sstvenc_cw_handle_state_dahspace(), sstvenc_cw_handle_state_ditspace(), sstvenc_cw_handle_state_done(), sstvenc_cw_handle_state_mark(), SSTVENC_CW_MOD_STATE_DAHSPACE, SSTVENC_CW_MOD_STATE_DITSPACE, SSTVENC_CW_MOD_STATE_DONE, SSTVENC_CW_MOD_STATE_INIT, SSTVENC_CW_MOD_STATE_MARK, SSTVENC_CW_MOD_STATE_NEXT_SYM, and sstvenc_cw_mod::state.

Referenced by main(), sstvenc_cw_fill_buffer(), and sstvenc_sequencer_compute().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_end_subsym()

static void sstvenc_cw_end_subsym ( struct sstvenc_cw_mod *const cw)
static

Handle the end of a sub-symbol (dah or dit). This resets the pulse shaper then increments sstvenc_cw_mod::pos. If there's more sub-symbols we go back to state SSTVENC_CW_MOD_STATE_MARK, otherwise we enter state SSTVENC_CW_MOD_STATE_DAHSPACE.

Definition at line 432 of file cw.c.

432 {
434 cw->pos++;
435 if (cw->symbol->value[cw->pos]) {
436 /* We need to produce another mark */
439 } else {
440 /* End of the symbol */
443 }
444}
uint8_t pos
Definition cw.h:145
struct sstvenc_pulseshape ps
Definition cw.h:136
const char * value
Definition cw.c:20
const struct sstvenc_cw_pair * symbol
Definition cw.h:130
void sstvenc_ps_reset(struct sstvenc_pulseshape *const ps, double hold_time, uint8_t time_unit)
Definition pulseshape.c:21
#define SSTVENC_TS_UNIT_SECONDS
Definition timescale.h:36

References sstvenc_cw_mod::pos, sstvenc_cw_mod::ps, sstvenc_cw_handle_state_dahspace(), sstvenc_cw_handle_state_mark(), SSTVENC_CW_MOD_STATE_DAHSPACE, SSTVENC_CW_MOD_STATE_MARK, sstvenc_ps_reset(), SSTVENC_TS_UNIT_SECONDS, sstvenc_cw_mod::state, sstvenc_cw_mod::symbol, and sstvenc_cw_pair::value.

Referenced by sstvenc_cw_handle_state_ditspace(), and sstvenc_cw_handle_state_mark().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_end_symbol()

static void sstvenc_cw_end_symbol ( struct sstvenc_cw_mod *const cw)
static

Called at the end of a morse code symbol. This advances sstvenc_cw_mod::text_string by the length of the sstvenc_cw_pair::key pointed to by sstvenc_cw_mod::symbol.

sstvenc_cw_mod::symbol is then dropped and we move on in state SSTVENC_CW_MOD_STATE_NEXT_SYM.

Definition at line 446 of file cw.c.

446 {
448 cw->text_string += strlen(cw->symbol->key);
449 cw->symbol = NULL;
452}
const char * text_string
Definition cw.h:127
const char * key
Definition cw.c:19

References sstvenc_cw_pair::key, sstvenc_cw_mod::ps, sstvenc_cw_get_next_sym(), SSTVENC_CW_MOD_STATE_NEXT_SYM, sstvenc_ps_reset(), SSTVENC_TS_UNIT_SECONDS, sstvenc_cw_mod::state, sstvenc_cw_mod::symbol, and sstvenc_cw_mod::text_string.

Referenced by sstvenc_cw_handle_state_dahspace().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_fill_buffer()

size_t sstvenc_cw_fill_buffer ( struct sstvenc_cw_mod *const cw,
double * buffer,
size_t buffer_sz )

Fill the given buffer with audio samples from the CW modulator. Stop if we run out of buffer space or if the CW state machine finishes. Return the number of samples generated.

Parameters
[in,out]cwCW state machine to pull samples from.
[out]bufferAudio buffer to write samples to.
[in]buffer_szSize of the audio buffer in samples.
Returns
Number of samples written to buffer

Definition at line 529 of file cw.c.

530 {
531 size_t written_sz = 0;
532
533 while ((buffer_sz > 0) && (cw->state < SSTVENC_CW_MOD_STATE_DONE)) {
535
536 buffer[0] = cw->output;
537 buffer++;
538 buffer_sz--;
539
540 written_sz++;
541 }
542
543 return written_sz;
544}
double output
Definition cw.h:114

References sstvenc_cw_mod::output, sstvenc_cw_compute(), SSTVENC_CW_MOD_STATE_DONE, and sstvenc_cw_mod::state.

Here is the call graph for this function:

◆ sstvenc_cw_get_next_sym()

static void sstvenc_cw_get_next_sym ( struct sstvenc_cw_mod *const cw)
static

Scan the string given in sstvenc_cw_mod::text_string by repeatedly calling sstvenc_cw_symbol_lookup.

If the text at sstvenc_cw_mod::text_string does not match a known symbol, we increment that and try again (until we run out of characters in sstvenc_cw_mod::text_string).

If we run out of characters, we move the state machine to SSTVENC_CW_MOD_STATE_DONE – we are finished.

Otherwise, we load the symbol into sstvenc_cw_mod::symbol, reset sstvenc_cw_mod::pos and enter SSTVENC_CW_MOD_STATE_MARK.

Definition at line 383 of file cw.c.

383 {
384 while ((cw->symbol == NULL) && cw->text_string[0]) {
385 /* Look up the next symbol in the string */
387 if (cw->symbol == NULL) {
388 /* Nothing here, advance to the next position */
389 cw->text_string++;
390 }
391 }
392
393 if (cw->symbol) {
394 /* We have a character, reset the position */
396 cw->pos = 0;
397
398 /* Process the mark so we have a valid output sample */
400 } else {
403 }
404}
static const struct sstvenc_cw_pair * sstvenc_cw_get_symbol(const char *sym)
Definition cw.c:365

References sstvenc_cw_mod::pos, sstvenc_cw_get_symbol(), sstvenc_cw_handle_state_done(), sstvenc_cw_handle_state_mark(), SSTVENC_CW_MOD_STATE_DONE, SSTVENC_CW_MOD_STATE_MARK, sstvenc_cw_mod::state, sstvenc_cw_mod::symbol, and sstvenc_cw_mod::text_string.

Referenced by sstvenc_cw_compute(), and sstvenc_cw_end_symbol().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_get_symbol()

static const struct sstvenc_cw_pair * sstvenc_cw_get_symbol ( const char * sym)
static

Try to locate the CW symbol that represents the text at the start of the string sym. First, sstvenc_cw_symbols is searched for the most likely case (English letters, digits and punctuation), then if that fails, sstvenc_cw_mbsymbols is scanned (non-English symbols and prosigns).

Parameters
[in]symThe text to be matched to a morse-code symbol. Assumed to be UTF-8 encoding.
Returns
The matching sstvenc_cw_pair for the symbol seen at the start of sym.
Return values
NULLThe character sequence seen at the start of sym does not match any known morse code symbol.

Definition at line 365 of file cw.c.

365 {
366 /* Short-cut, look for single character symbols first */
367 const struct sstvenc_cw_pair* match
369 if (match) {
370 return match;
371 }
372
373 /* Try searching the multi-byte table */
375 if (match) {
376 return match;
377 }
378
379 /* Nothing found */
380 return NULL;
381}
static struct sstvenc_cw_pair sstvenc_cw_mbsymbols[]
Definition cw.c:99
static struct sstvenc_cw_pair sstvenc_cw_symbols[]
Definition cw.c:33
static const struct sstvenc_cw_pair * sstvenc_cw_symbol_lookup(const char *sym, const struct sstvenc_cw_pair *table, uint8_t len)
Definition cw.c:342

References sstvenc_cw_mbsymbols, sstvenc_cw_symbol_lookup(), and sstvenc_cw_symbols.

Referenced by sstvenc_cw_get_next_sym().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_handle_state_dahspace()

static void sstvenc_cw_handle_state_dahspace ( struct sstvenc_cw_mod *const cw)
static

Handling of the spaces between symbols (morse code symbols). This is the length of one "dah" (3 "dits"), and is measured by sstvenc_pulseshape::sample_idx which is incremented each time sstvenc_ps_compute is called whilst the shaper remains in the SSTVENC_PS_PHASE_DONE state.

As we enter this state after being in the SSTVENC_CW_MOD_STATE_DITSPACE state, one "dit"'s worth of space has already been emitted, so we carry on.

When it passes sstvenc_cw_mod::dit_period * 2, we call sstvenc_cw_end_symbol to move to the next symbol.

Definition at line 493 of file cw.c.

493 {
494 sstvenc_ps_compute(&(cw->ps));
495 if (cw->ps.sample_idx > (2 * cw->dit_period)) {
496 /* That's enough space. */
498 }
499}
uint16_t dit_period
Definition cw.h:139
static void sstvenc_cw_end_symbol(struct sstvenc_cw_mod *const cw)
Definition cw.c:446
uint32_t sample_idx
Definition pulseshape.h:97
void sstvenc_ps_compute(struct sstvenc_pulseshape *const ps)
Definition pulseshape.c:63

References sstvenc_cw_mod::dit_period, sstvenc_cw_mod::ps, sstvenc_pulseshape::sample_idx, sstvenc_cw_end_symbol(), and sstvenc_ps_compute().

Referenced by sstvenc_cw_compute(), and sstvenc_cw_end_subsym().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_handle_state_ditspace()

static void sstvenc_cw_handle_state_ditspace ( struct sstvenc_cw_mod *const cw)
static

Handling of the spaces between sub-symbols (individual dahs and dits). This is the length of one "dit", and is measured by sstvenc_pulseshape::sample_idx which is incremented each time sstvenc_ps_compute is called whilst the shaper remains in the SSTVENC_PS_PHASE_DONE state.

When it passes sstvenc_cw_mod::dit_period, we call sstvenc_cw_end_subsym to move to the next sub-symbol.

Definition at line 484 of file cw.c.

484 {
485 sstvenc_ps_compute(&(cw->ps));
486 if (cw->ps.sample_idx > cw->dit_period) {
487 /* That's enough space. */
489 }
490}
static void sstvenc_cw_end_subsym(struct sstvenc_cw_mod *const cw)
Definition cw.c:432

References sstvenc_cw_mod::dit_period, sstvenc_cw_mod::ps, sstvenc_pulseshape::sample_idx, sstvenc_cw_end_subsym(), and sstvenc_ps_compute().

Referenced by sstvenc_cw_compute(), and sstvenc_cw_handle_state_mark().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_handle_state_done()

static void sstvenc_cw_handle_state_done ( struct sstvenc_cw_mod *const cw)
static

Handling of the end of transmission. We reset state variables and the output so it emits zeroes from now on.

Definition at line 501 of file cw.c.

501 {
502 cw->output = 0.0;
503 cw->text_string = NULL;
504 cw->symbol = NULL;
505}

References sstvenc_cw_mod::output, sstvenc_cw_mod::symbol, and sstvenc_cw_mod::text_string.

Referenced by sstvenc_cw_compute(), and sstvenc_cw_get_next_sym().

Here is the caller graph for this function:

◆ sstvenc_cw_handle_state_mark()

static void sstvenc_cw_handle_state_mark ( struct sstvenc_cw_mod *const cw)
static

Sub-state machine built around the pulse shaper state machine to handle transmission of a mark. This routine initialises the pulse shaper by calling sstvenc_cw_start_mark then will step the pulse shaper through its state machine by calling sstvenc_ps_compute.

The envelope is modulated by the oscillator by calling sstvenc_osc_compute then multiplying the outputs, storing these in sstvenc_cw_mod::output.

At the end of the envelope, it resets sstvenc_cw_mod::output. If we were actually transmitting a space, we move to the next sub-symbol otherwise we enter SSTVENC_CW_MOD_STATE_DITSPACE to emit the inter-sub-symbol dit space.

Definition at line 454 of file cw.c.

454 {
455 switch (cw->ps.phase) {
457 /* Start of a dah/dit/space */
459 /* Fall thru */
463 /* Dah/Dit in progress */
464 sstvenc_ps_compute(&(cw->ps));
465 sstvenc_osc_compute(&(cw->osc));
466 cw->output = cw->ps.output * cw->osc.output;
467 break;
469 /* Dah/Dit finished, space starts here */
470 cw->output = 0.0;
471 cw->osc.amplitude = 0.0;
472 if (cw->symbol->value[cw->pos] == ' ') {
473 /* This was actually a space, don't add more! */
475 } else {
476 sstvenc_ps_compute(&(cw->ps));
479 }
480 }
481}
struct sstvenc_oscillator osc
Definition cw.h:133
static void sstvenc_cw_start_mark(struct sstvenc_cw_mod *const cw)
Definition cw.c:406
void sstvenc_osc_compute(struct sstvenc_oscillator *const osc)
Definition oscillator.c:52
#define SSTVENC_PS_PHASE_HOLD
Definition pulseshape.h:58
#define SSTVENC_PS_PHASE_FALL
Definition pulseshape.h:67
#define SSTVENC_PS_PHASE_INIT
Definition pulseshape.h:35
#define SSTVENC_PS_PHASE_RISE
Definition pulseshape.h:44
#define SSTVENC_PS_PHASE_DONE
Definition pulseshape.h:75

References sstvenc_oscillator::amplitude, sstvenc_cw_mod::osc, sstvenc_cw_mod::output, sstvenc_oscillator::output, sstvenc_pulseshape::output, sstvenc_pulseshape::phase, sstvenc_cw_mod::pos, sstvenc_cw_mod::ps, sstvenc_cw_end_subsym(), sstvenc_cw_handle_state_ditspace(), SSTVENC_CW_MOD_STATE_DITSPACE, sstvenc_cw_start_mark(), sstvenc_osc_compute(), sstvenc_ps_compute(), SSTVENC_PS_PHASE_DONE, SSTVENC_PS_PHASE_FALL, SSTVENC_PS_PHASE_HOLD, SSTVENC_PS_PHASE_INIT, SSTVENC_PS_PHASE_RISE, sstvenc_cw_mod::state, sstvenc_cw_mod::symbol, and sstvenc_cw_pair::value.

Referenced by sstvenc_cw_compute(), sstvenc_cw_end_subsym(), and sstvenc_cw_get_next_sym().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_init()

void sstvenc_cw_init ( struct sstvenc_cw_mod *const cw,
const char * text,
double amplitude,
double frequency,
double dit_period,
double slope_period,
uint32_t sample_rate,
uint8_t time_unit )

Initialise a CW state machine.

Parameters
[in,out]cwCW state machine context being initialised.
[in]textText to transmit in CW (morse code)
[in]amplitudePeak amplitude of the carrier on the scale 0.0-1.0.
[in]frequencyOscillator frequency in Hz.
[in]dit_periodThe length of a morse code 'dit'.
[in]slope_periodThe duration used for rising and falling pulse edges for bandwidth reduction.
[in]sample_rateThe sample rate of the output waveform in hertz.
[in]time_unitThe time unit used for measuring dit_period and slope_period.

Definition at line 312 of file cw.c.

315 {
316
317 sstvenc_ps_init(&(cw->ps), amplitude, slope_period, INFINITY,
318 slope_period, sample_rate, time_unit);
319 sstvenc_osc_init(&(cw->osc), 1.0, frequency, 0.0, sample_rate);
320 cw->dit_period
321 = sstvenc_ts_unit_to_samples(dit_period, sample_rate, time_unit);
322 cw->pos = 0;
323 cw->symbol = NULL;
324 cw->text_string = text;
326}
void sstvenc_osc_init(struct sstvenc_oscillator *const osc, double amplitude, double frequency, double offset, uint32_t sample_rate)
Definition oscillator.c:42
void sstvenc_ps_init(struct sstvenc_pulseshape *const ps, double amplitude, double rise_time, double hold_time, double fall_time, uint32_t sample_rate, uint8_t time_unit)
Definition pulseshape.c:28
uint32_t sstvenc_ts_unit_to_samples(double time, uint32_t sample_rate, uint8_t unit)
Definition timescale.c:46

References sstvenc_cw_mod::dit_period, sstvenc_cw_mod::osc, sstvenc_cw_mod::pos, sstvenc_cw_mod::ps, SSTVENC_CW_MOD_STATE_INIT, sstvenc_osc_init(), sstvenc_ps_init(), sstvenc_ts_unit_to_samples(), sstvenc_cw_mod::state, sstvenc_cw_mod::symbol, and sstvenc_cw_mod::text_string.

Referenced by main(), and sstvenc_sequencer_begin_cw().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_start_mark()

static void sstvenc_cw_start_mark ( struct sstvenc_cw_mod *const cw)
static

Prepare to transmit a "mark" (or a gap between marks).

sstvenc_cw_mod::pos gives the position in the current morse-code symbol being processed. It points to either ‘’ ','.'or'-'`.

For a ‘’ '`: the oscillator amplitude is set to 0.0 and we reset the pulse shaper for the duration of a single dit.

For a ‘’.'`: the oscillator amplitude is set to 1.0 and we reset the pulse shaper for the duration of a single dit.

For a ‘’-'`: the oscillator amplitude is set to 1.0 and we reset the pulse shaper for the duration of three dits.

Definition at line 406 of file cw.c.

406 {
407 switch (cw->symbol->value[cw->pos]) {
408 case ' ':
409 /* A space */
410 cw->osc.amplitude = 0.0;
412 - cw->ps.rise_sz
413 - cw->ps.fall_sz);
414 break;
415 case '.':
416 /* A dit */
417 cw->osc.amplitude = 1.0;
419 - cw->ps.rise_sz
420 - cw->ps.fall_sz);
421 break;
422 case '-':
423 /* A dah */
424 cw->osc.amplitude = 1.0;
425 sstvenc_ps_reset_samples(&(cw->ps), (cw->dit_period * 3)
426 - cw->ps.rise_sz
427 - cw->ps.fall_sz);
428 break;
429 }
430}
void sstvenc_ps_reset_samples(struct sstvenc_pulseshape *const ps, uint32_t hold_time)
Definition pulseshape.c:14

References sstvenc_oscillator::amplitude, sstvenc_cw_mod::dit_period, sstvenc_pulseshape::fall_sz, sstvenc_cw_mod::osc, sstvenc_cw_mod::pos, sstvenc_cw_mod::ps, sstvenc_pulseshape::rise_sz, sstvenc_ps_reset_samples(), sstvenc_cw_mod::symbol, and sstvenc_cw_pair::value.

Referenced by sstvenc_cw_handle_state_mark().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_symbol_lookup()

static const struct sstvenc_cw_pair * sstvenc_cw_symbol_lookup ( const char * sym,
const struct sstvenc_cw_pair * table,
uint8_t len )
static

Look up the symbol at the start of sym in the table table.

Parameters
[in]symText symbol being looked up. May be followed by other symbols. Assumed UTF-8 encoding.
[in]tableSymbol table to scan for possible matches. The table must be terminated by a sstvenc_cw_pair with both sstvenc_cw_pair::key and sstvenc_cw_pair::value set to NULL.
[in]lenThe fixed symbol length to check. For sstvenc_cw_symbols, all values are single byte ASCII characters, so in that situation, set this parameter to 1. This optimises the most likely case: plain English characters.
                            If the symbols are a variable length, which is
                            the case for sstvenc_cw_mbsymbols, set this to
                            0 instead.
Returns
The matching sstvenc_cw_pair for the symbol seen at the start of sym.
Return values
NULLNone of the symbols in table match the character sequence at sym.

Definition at line 342 of file cw.c.

343 {
344 while (table->key) {
345 if (len) {
346 /* Known length, compare the symbols */
347 if (!strncmp(sym, table->key, len)
348 && (table->key[len] == 0)) {
349 /* Return the match */
350 return table;
351 }
352 } else {
353 const struct sstvenc_cw_pair* match
354 = sstvenc_cw_symbol_match(sym, table);
355 if (match) {
356 return match;
357 }
358 }
359 table++;
360 }
361
362 return NULL;
363}
static const struct sstvenc_cw_pair * sstvenc_cw_symbol_match(const char *sym, const struct sstvenc_cw_pair *candidate)
Definition cw.c:329

References sstvenc_cw_pair::key, and sstvenc_cw_symbol_match().

Referenced by sstvenc_cw_get_symbol().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sstvenc_cw_symbol_match()

static const struct sstvenc_cw_pair * sstvenc_cw_symbol_match ( const char * sym,
const struct sstvenc_cw_pair * candidate )
static

Compare the character sequence given to the candidate symbol.

Parameters
[in]symText symbol to be compared. May be followed by other symbols. Assumed UTF-8 encoding.
[in]candidateCandidate morse code symbol being compared. The string sym is a match if it starts with the sstvenc_cw_pair::key given by candidate.
Return values
candidateThe candidate is a match.
NULLNot a match.

Definition at line 329 of file cw.c.

330 {
331 /* Check match */
332 if (!strncmp(sym, candidate->key, strlen(candidate->key))) {
333 /* Return the match */
334 return candidate;
335 } else {
336 /* Not a match */
337 return NULL;
338 }
339}

References sstvenc_cw_pair::key.

Referenced by sstvenc_cw_symbol_lookup().

Here is the caller graph for this function:

Variable Documentation

◆ sstvenc_cw_mbsymbols

struct sstvenc_cw_pair sstvenc_cw_mbsymbols[]
static

Multi-byte symbols. These symbols have keys that are more than one byte each. Non-English and CW prosigns.

Definition at line 99 of file cw.c.

99 {
100 /* Non-English */
101 {.key = "À", .value = ".--.-"}, /* also Å */
102 {.key = "Ä", .value = ".-.-"}, /* also Æ Ą */
103 {.key = "Å", .value = ".--.-"},
104 {.key = "Æ", .value = ".-.-"},
105 {.key = "Ą", .value = ".-.-"},
106 {.key = "Ć", .value = "-.-.."}, /* also Ĉ Ç */
107 {.key = "Ĉ", .value = "-.-.."},
108 {.key = "Ç", .value = "-.-.."},
109 {.key = "Ð", .value = "..--."},
110 {.key = "É", .value = "..-.."}, /* also Ę */
111 {.key = "È", .value = ".-..-"}, /* also Ł */
112 {.key = "Ę", .value = "..-.."},
113 {.key = "Ĝ", .value = "--.-."},
114 {.key = "Ĥ", .value = "----"}, /* also <CH> Š */
115 {.key = "Ĵ", .value = ".---."},
116 {.key = "Ł", .value = ".-..-"},
117 {.key = "Ń", .value = "--.--"}, /* also Ñ */
118 {.key = "Ñ", .value = "--.--"},
119 {.key = "Ó", .value = "---."}, /* also Ö Ø */
120 {.key = "Ö", .value = "---."},
121 {.key = "Ø", .value = "---."},
122 {.key = "Ś", .value = "...-..."},
123 {.key = "Ŝ", .value = "...-."},
124 {.key = "Š", .value = "----"},
125 {.key = "Þ", .value = ".--.."},
126 {.key = "Ü", .value = "..--"}, /* also Ŭ */
127 {.key = "Ŭ", .value = "..--"},
128 {.key = "Ź", .value = "--..-."},
129 {.key = "Ż", .value = "--..-"},
130 {.key = "<CH>", .value = "----"},
131 /*
132 * Prosigns: since < and > are not valid, we use these to
133 * define the start and end of a prosign name.
134 */
135 {.key = "<END_OF_WORK>", .value = "...-.-"},
136 {.key = "<ERROR>", .value = "........"},
137 {.key = "<INVITATION>", .value = "-.-"},
138 {.key = "<START>", .value = "-.-.-"},
139 {.key = "<NEW_MESSAGE>", .value = ".-.-."},
140 {.key = "<VERIFIED>", .value = "...-."},
141 {.key = "<WAIT>", .value = ".-..."},
142 {.key = NULL, .value = NULL},
143};

Referenced by sstvenc_cw_get_symbol().

◆ sstvenc_cw_symbols

struct sstvenc_cw_pair sstvenc_cw_symbols[]
static

Symbol table… UTF-8 symbol mapped to the morse code sequence that represents it. This table is for single-byte sequences only.

The values are strings where the characters have the following meanings:

  • '.': a tone the length of a 'dit'
  • '-': a tone the length of a 'dah' (3 dits)
  • ' ': a dit's worth of space, this is a special-case kludge used to handle the space character between words.

Definition at line 33 of file cw.c.

33 {
34 /* Whitespace */
35 {.key = " ", .value = " "}, /* NB: some space is already added */
36 /* Letters */
37 {.key = "A", .value = ".-"},
38 {.key = "B", .value = "-..."},
39 {.key = "C", .value = "-.-."},
40 {.key = "D", .value = "-.."},
41 {.key = "E", .value = "."},
42 {.key = "F", .value = "..-."},
43 {.key = "G", .value = "--."},
44 {.key = "H", .value = "...."},
45 {.key = "I", .value = ".."},
46 {.key = "J", .value = ".---"},
47 {.key = "K", .value = "-.-"},
48 {.key = "L", .value = ".-.."},
49 {.key = "M", .value = "--"},
50 {.key = "N", .value = "-."},
51 {.key = "O", .value = "---"},
52 {.key = "P", .value = ".--."},
53 {.key = "Q", .value = "--.-"},
54 {.key = "R", .value = ".-."},
55 {.key = "S", .value = "..."},
56 {.key = "T", .value = "-"},
57 {.key = "U", .value = "..-"},
58 {.key = "V", .value = "...-"},
59 {.key = "W", .value = ".--"},
60 {.key = "X", .value = "-..-"},
61 {.key = "Y", .value = "-.--"},
62 {.key = "Z", .value = "--.."},
63 /* Digits */
64 {.key = "0", .value = "-----"},
65 {.key = "1", .value = ".----"},
66 {.key = "2", .value = "..---"},
67 {.key = "3", .value = "...--"},
68 {.key = "4", .value = "....-"},
69 {.key = "5", .value = "....."},
70 {.key = "6", .value = "-...."},
71 {.key = "7", .value = "--..."},
72 {.key = "8", .value = "---.."},
73 {.key = "9", .value = "----."},
74 /* Symbols */
75 {.key = ".", .value = ".-.-.-"},
76 {.key = ",", .value = "--..--"},
77 {.key = "?", .value = "..--.."},
78 {.key = "'", .value = ".----."},
79 {.key = "!", .value = "-.-.--"},
80 {.key = "/", .value = "-..-."},
81 {.key = "(", .value = "-.--."},
82 {.key = ")", .value = "-.--.-"},
83 {.key = "&", .value = ".-..."},
84 {.key = ":", .value = "---..."},
85 {.key = "=", .value = "-...-"},
86 {.key = "+", .value = ".-.-."},
87 {.key = "-", .value = "-....-"},
88 {.key = "_", .value = "..--.-"},
89 {.key = "\"", .value = ".-..-."},
90 {.key = "$", .value = "...-..-"},
91 {.key = "@", .value = ".--.-."},
92 {.key = NULL, .value = NULL},
93};

Referenced by sstvenc_cw_get_symbol().