libsstvenc
Asynchronous Analogue SSTV encoder
Loading...
Searching...
No Matches
sequence.c
Go to the documentation of this file.
1
6/*
7 * © Stuart Longland VK4MSL
8 * SPDX-License-Identifier: MIT
9 */
10
11#include <libsstvenc/sequence.h>
12
14 struct sstvenc_sequencer_step* const step, uint8_t time_unit,
15 _Bool convert) {
17 step->args.ts.time_unit = time_unit;
18 step->args.ts.convert = convert;
19}
20
29static void
31 uint8_t type, uint8_t reg, double value) {
32 step->type = type;
33 step->args.reg.reg = reg;
34 step->args.reg.value = value;
35}
36
38 uint8_t reg, double value) {
40 step, SSTVENC_SEQ_STEP_TYPE_SET_REGISTER, reg, value);
41}
42
44 uint8_t reg, double value) {
46 step, SSTVENC_SEQ_STEP_TYPE_INC_REGISTER, reg, value);
47}
48
50 uint8_t reg, double value) {
52 step, SSTVENC_SEQ_STEP_TYPE_DEC_REGISTER, reg, value);
53}
54
56 uint8_t reg, double value) {
58 step, SSTVENC_SEQ_STEP_TYPE_MUL_REGISTER, reg, value);
59}
60
62 uint8_t reg, double value) {
64 step, SSTVENC_SEQ_STEP_TYPE_DIV_REGISTER, reg, value);
65}
66
68 struct sstvenc_sequencer_step* const step, uint8_t reg, double value) {
70 step, SSTVENC_SEQ_STEP_TYPE_IDEC_REGISTER, reg, value);
71}
72
74 struct sstvenc_sequencer_step* const step, uint8_t reg, double value) {
76 step, SSTVENC_SEQ_STEP_TYPE_IDIV_REGISTER, reg, value);
77}
78
85static void
87 uint8_t type, double duration) {
88 step->type = type;
89 step->args.duration.duration = duration;
90}
91
93 double duration) {
96}
97
99 double duration, uint8_t slopes) {
101 duration);
102 step->args.duration.slopes = slopes;
103}
104
106 const char* text) {
108 step->args.cw.text = text;
109}
110
112 const struct sstvenc_mode* const mode,
113 const uint8_t* framebuffer,
114 const char* fsk_id) {
116 step->args.image.mode = mode;
117 step->args.image.framebuffer = framebuffer;
118 step->args.image.fsk_id = fsk_id;
119}
120
124
126 const struct sstvenc_sequencer_step* steps,
128 const void* event_cb_ctx, uint32_t sample_rate) {
129 seq->steps = steps;
130 seq->event_cb = event_cb;
131 seq->event_cb_ctx = event_cb_ctx;
133}
134
139static void sstvenc_sequencer_next_step(struct sstvenc_sequencer* const seq,
140 _Bool notify) {
141 seq->step++;
142
143 if (notify && seq->event_cb) {
144 seq->event_cb(seq);
145 }
146}
147
153 uint8_t state, _Bool notify) {
154 if (seq->state != state) {
155 seq->state = state;
156
157 if (notify && seq->event_cb) {
158 seq->event_cb(seq);
159 }
160 }
161}
162
167 struct sstvenc_sequencer* const seq,
168 const struct sstvenc_sequencer_step* const step) {
169 /* Perform conversions if asked */
170 if (step->args.ts.convert) {
171 const uint64_t old_scale
173 const uint64_t new_scale
175 double scale = (double)new_scale / (double)old_scale;
176
177 for (uint8_t reg = 0; reg < SSTVENC_SEQ_NUM_REGS; reg++) {
178 seq->regs[reg] *= scale;
179 }
180 }
181
182 /* Apply new unit setting */
183 seq->time_unit = step->args.ts.time_unit;
184
185 /* Step is complete */
187}
188
193 struct sstvenc_sequencer* const seq,
194 const struct sstvenc_sequencer_step* const step) {
195 if (step->args.reg.reg < SSTVENC_SEQ_NUM_REGS) {
196 /* Get a pointer to the register for convenience */
197 double* const value = &(seq->regs[step->args.reg.reg]);
198
199 switch (step->type) {
201 *value = step->args.reg.value;
202 break;
204 *value += step->args.reg.value;
205 break;
207 *value -= step->args.reg.value;
208 break;
210 *value *= step->args.reg.value;
211 break;
213 *value /= step->args.reg.value;
214 break;
216 *value = step->args.reg.value - *value;
217 break;
219 *value = step->args.reg.value / *value;
220 break;
221 }
222 }
223
224 /* Step is complete */
226}
227
232 struct sstvenc_sequencer* const seq,
233 const struct sstvenc_sequencer_step* const step) {
235 true);
236
237 if (step->args.duration.duration == INFINITY) {
240 } else {
242 step->args.duration.duration, seq->sample_rate,
243 seq->time_unit);
246 }
247}
248
250 struct sstvenc_sequencer* const seq,
251 const struct sstvenc_sequencer_step* const step) {
252 _Bool init_osc = seq->state != SSTVENC_SEQ_STATE_END_TONE;
254 true);
255
260 : 0.0,
261 step->args.duration.duration,
264 : 0.0,
265 seq->sample_rate, seq->time_unit);
266
267 if (init_osc) {
268 sstvenc_osc_init(&(seq->vars.tone.osc), 0.0,
271 seq->sample_rate);
272 } else {
274 &(seq->vars.tone.osc),
277 }
278
279 if (step->args.duration.duration == INFINITY) {
282 } else {
284 true);
285 }
286}
287
288static void
302
319
323
360
362 seq->step = 0;
365 seq->regs[SSTVENC_SEQ_REG_FREQUENCY] = 800.0;
366 seq->regs[SSTVENC_SEQ_REG_PHASE] = 0.0;
367 seq->regs[SSTVENC_SEQ_REG_PULSE_RISE] = 0.002;
368 seq->regs[SSTVENC_SEQ_REG_PULSE_FALL] = 0.002;
369 seq->regs[SSTVENC_SEQ_REG_DIT_PERIOD] = 0.05;
371}
372
374 switch (seq->state) {
379 break;
382 break;
383 default:
384 return;
385 }
386}
387
389retry:
390 switch (seq->state) {
397 goto retry;
398 break;
402 seq->output = 0.0;
403 if (seq->vars.silence.remaining > 0) {
404 seq->vars.silence.remaining--;
405 } else {
408 goto retry;
409 }
410 break;
415 seq->vars.tone.osc.amplitude = seq->vars.tone.ps.output;
417 seq->output = seq->vars.tone.osc.output;
418
419 if (seq->vars.tone.ps.phase >= SSTVENC_PS_PHASE_DONE) {
421 seq, SSTVENC_SEQ_STATE_END_TONE, true);
422 goto retry;
423 }
424 break;
427 sstvenc_cw_compute(&(seq->vars.cw));
428 seq->output = seq->vars.cw.output;
429
432 seq, SSTVENC_SEQ_STATE_END_CW, true);
433 goto retry;
434 }
435 break;
439 seq->output = seq->vars.sstv.osc.output;
440
441 if (seq->vars.sstv.ps.phase >= SSTVENC_PS_PHASE_DONE) {
443 seq, SSTVENC_SEQ_STATE_END_IMAGE, true);
444 goto retry;
445 }
446 break;
448 default:
449 break;
450 }
451}
452
454 double* buffer, size_t buffer_sz) {
455 size_t written_sz = 0;
456
457 while ((buffer_sz > 0) && (seq->state < SSTVENC_SEQ_STATE_DONE)) {
459
460 buffer[0] = seq->output;
461 buffer++;
462 buffer_sz--;
463
464 written_sz++;
465 }
466
467 return written_sz;
468}
#define SSTVENC_CW_MOD_STATE_DONE
Definition cw.h:91
double output
Definition cw.h:114
uint8_t state
Definition cw.h:142
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
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_osc_set_frequency(struct sstvenc_oscillator *const osc, double frequency)
Definition oscillator.c:33
void sstvenc_osc_compute(struct sstvenc_oscillator *const osc)
Definition oscillator.c:52
#define SSTVENC_PS_PHASE_DONE
Definition pulseshape.h:75
void sstvenc_ps_advance(struct sstvenc_pulseshape *const ps)
Definition pulseshape.c:56
void sstvenc_ps_compute(struct sstvenc_pulseshape *const ps)
Definition pulseshape.c:63
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
#define SSTVENC_SEQ_REG_PULSE_FALL
Definition sequence.h:285
#define SSTVENC_SEQ_REG_DIT_PERIOD
Definition sequence.h:290
#define SSTVENC_SEQ_NUM_REGS
Definition sequence.h:295
#define SSTVENC_SEQ_REG_FREQUENCY
Definition sequence.h:270
#define SSTVENC_SEQ_REG_PHASE
Definition sequence.h:275
#define SSTVENC_SEQ_REG_AMPLITUDE
Definition sequence.h:265
#define SSTVENC_SEQ_REG_PULSE_RISE
Definition sequence.h:280
#define SSTVENC_SEQ_STATE_GEN_SILENCE
Definition sequence.h:60
#define SSTVENC_SEQ_STATE_END_CW
Definition sequence.h:140
#define SSTVENC_SEQ_STATE_BEGIN_SILENCE
Definition sequence.h:53
#define SSTVENC_SEQ_STATE_GEN_IMAGE
Definition sequence.h:154
#define SSTVENC_SEQ_STATE_INIT
Definition sequence.h:45
#define SSTVENC_SEQ_STATE_END_IMAGE
Definition sequence.h:165
#define SSTVENC_SEQ_STATE_BEGIN_CW
Definition sequence.h:122
#define SSTVENC_SEQ_STATE_END_SILENCE
Definition sequence.h:79
#define SSTVENC_SEQ_STATE_DONE
Definition sequence.h:170
#define SSTVENC_SEQ_STATE_BEGIN_TONE
Definition sequence.h:87
#define SSTVENC_SEQ_STATE_END_TONE
Definition sequence.h:115
#define SSTVENC_SEQ_STATE_GEN_INF_SILENCE
Definition sequence.h:67
#define SSTVENC_SEQ_STATE_GEN_INF_TONE
Definition sequence.h:104
#define SSTVENC_SEQ_STATE_GEN_CW
Definition sequence.h:129
#define SSTVENC_SEQ_STATE_BEGIN_IMAGE
Definition sequence.h:147
#define SSTVENC_SEQ_STATE_GEN_TONE
Definition sequence.h:95
#define SSTVENC_SEQ_STEP_TYPE_DIV_REGISTER
Definition sequence.h:220
#define SSTVENC_SEQ_STEP_TYPE_EMIT_IMAGE
Definition sequence.h:251
#define SSTVENC_SEQ_STEP_TYPE_SET_REGISTER
Definition sequence.h:200
#define SSTVENC_SEQ_STEP_TYPE_DEC_REGISTER
Definition sequence.h:210
#define SSTVENC_SEQ_STEP_TYPE_END
Definition sequence.h:190
#define SSTVENC_SEQ_STEP_TYPE_IDEC_REGISTER
Definition sequence.h:226
#define SSTVENC_SEQ_STEP_TYPE_SET_TS_UNIT
Definition sequence.h:195
#define SSTVENC_SEQ_STEP_TYPE_INC_REGISTER
Definition sequence.h:205
#define SSTVENC_SEQ_STEP_TYPE_MUL_REGISTER
Definition sequence.h:215
#define SSTVENC_SEQ_STEP_TYPE_IDIV_REGISTER
Definition sequence.h:231
#define SSTVENC_SEQ_STEP_TYPE_EMIT_SILENCE
Definition sequence.h:236
#define SSTVENC_SEQ_STEP_TYPE_EMIT_TONE
Definition sequence.h:241
#define SSTVENC_SEQ_STEP_TYPE_EMIT_CW
Definition sequence.h:246
#define SSTVENC_SEQ_SLOPE_RISING
Definition sequence.h:310
#define SSTVENC_SEQ_SLOPE_FALLING
Definition sequence.h:311
sstvenc_sequencer_event_cb * event_cb
Definition sequence.h:338
void sstvenc_sequencer_event_cb(struct sstvenc_sequencer *const enc)
Definition sequence.h:327
static void sstvenc_sequencer_step_update_reg(struct sstvenc_sequencer_step *const step, uint8_t type, uint8_t reg, double value)
Definition sequence.c:30
void sstvenc_sequencer_step_dec_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:49
void sstvenc_sequencer_step_mul_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:55
const void * event_cb_ctx
Definition sequence.h:341
void sstvenc_sequencer_step_tone(struct sstvenc_sequencer_step *const step, double duration, uint8_t slopes)
Definition sequence.c:98
static void sstvenc_sequencer_begin_image(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *const step)
Definition sequence.c:303
struct sstvenc_sequencer_step::sstvenc_sequence_step_args::sstvenc_sequence_step_duration duration
uint32_t sample_rate
Definition sequence.h:385
struct sstvenc_sequencer_step::sstvenc_sequence_step_args::sstvenc_sequence_step_set_reg reg
union sstvenc_sequencer::sstvenc_sequencer_vars vars
void sstvenc_sequencer_step_inc_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:43
uint8_t time_unit
Definition sequence.h:394
struct sstvenc_sequencer::sstvenc_sequencer_vars::sstvenc_sequencer_vars_silence silence
void sstvenc_sequencer_step_div_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:61
void sstvenc_sequencer_step_set_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:37
void sstvenc_sequencer_step_end(struct sstvenc_sequencer_step *const step)
Definition sequence.c:121
static void sstvenc_sequencer_step_duration(struct sstvenc_sequencer_step *const step, uint8_t type, double duration)
Definition sequence.c:86
union sstvenc_sequencer_step::sstvenc_sequence_step_args args
struct sstvenc_sequencer_step::sstvenc_sequence_step_args::sstvenc_sequence_step_cw cw
void sstvenc_sequencer_step_idiv_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:73
static void sstvenc_sequencer_next_state(struct sstvenc_sequencer *const seq, uint8_t state, _Bool notify)
Definition sequence.c:152
void sstvenc_sequencer_step_image(struct sstvenc_sequencer_step *const step, const struct sstvenc_mode *const mode, const uint8_t *framebuffer, const char *fsk_id)
Definition sequence.c:111
static void sstvenc_sequencer_begin_cw(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *const step)
Definition sequence.c:289
static void sstvenc_sequencer_end(struct sstvenc_sequencer *const seq)
Definition sequence.c:320
const struct sstvenc_sequencer_step * steps
Definition sequence.h:335
struct sstvenc_sequencer::sstvenc_sequencer_vars::sstvenc_sequencer_vars_tone tone
void sstvenc_sequencer_step_cw(struct sstvenc_sequencer_step *const step, const char *text)
Definition sequence.c:105
struct sstvenc_sequencer_step::sstvenc_sequence_step_args::sstvenc_sequence_step_set_ts_unit ts
static void sstvenc_sequencer_exec_set_ts(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *const step)
Definition sequence.c:166
static void sstvenc_sequencer_exec_step(struct sstvenc_sequencer *const seq)
Definition sequence.c:327
void sstvenc_sequencer_step_set_timescale(struct sstvenc_sequencer_step *const step, uint8_t time_unit, _Bool convert)
Definition sequence.c:13
void sstvenc_sequencer_step_idec_reg(struct sstvenc_sequencer_step *const step, uint8_t reg, double value)
Definition sequence.c:67
double regs[SSTVENC_SEQ_NUM_REGS]
Definition sequence.h:380
void sstvenc_sequencer_step_silence(struct sstvenc_sequencer_step *const step, double duration)
Definition sequence.c:92
size_t sstvenc_sequencer_fill_buffer(struct sstvenc_sequencer *const seq, double *buffer, size_t buffer_sz)
Definition sequence.c:453
struct sstvenc_sequencer_step::sstvenc_sequence_step_args::sstvenc_sequence_step_image image
void sstvenc_sequencer_advance(struct sstvenc_sequencer *const seq)
Definition sequence.c:373
void sstvenc_sequencer_reset(struct sstvenc_sequencer *const seq)
Definition sequence.c:361
static void sstvenc_sequencer_next_step(struct sstvenc_sequencer *const seq, _Bool notify)
Definition sequence.c:139
static void sstvenc_sequencer_exec_update_reg(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *const step)
Definition sequence.c:192
static void sstvenc_sequencer_begin_silence(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *const step)
Definition sequence.c:231
void sstvenc_sequencer_init(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *steps, sstvenc_sequencer_event_cb *event_cb, const void *event_cb_ctx, uint32_t sample_rate)
Definition sequence.c:125
void sstvenc_sequencer_compute(struct sstvenc_sequencer *const seq)
Definition sequence.c:388
static void sstvenc_sequencer_begin_tone(struct sstvenc_sequencer *const seq, const struct sstvenc_sequencer_step *const step)
Definition sequence.c:249
struct sstvenc_oscillator osc
Definition sstvmod.h:42
struct sstvenc_pulseshape ps
Definition sstvmod.h:44
void sstvenc_modulator_init(struct sstvenc_mod *const mod, const struct sstvenc_mode *mode, const char *fsk_id, const uint8_t *framebuffer, double rise_time, double fall_time, uint32_t sample_rate, uint8_t time_unit)
Definition sstvmod.c:14
void sstvenc_modulator_compute(struct sstvenc_mod *const mod)
Definition sstvmod.c:125
#define SSTVENC_TS_UNIT_SECONDS
Definition timescale.h:36
uint64_t sstvenc_ts_unit_scale(uint8_t unit)
Definition timescale.c:22
uint32_t sstvenc_ts_unit_to_samples(double time, uint32_t sample_rate, uint8_t unit)
Definition timescale.c:46