libsstvenc
Asynchronous Analogue SSTV encoder
Loading...
Searching...
No Matches
Pulse Shaper
Collaboration diagram for Pulse Shaper:

Topics

 Pulse Shaper States
 

Data Structures

struct  sstvenc_pulseshape
 

Macros

#define SSTVENC_PS_HOLD_TIME_INF   SSTVENC_TS_INFINITE
 

Functions

void sstvenc_ps_reset_samples (struct sstvenc_pulseshape *const ps, uint32_t hold_time)
 
void sstvenc_ps_reset (struct sstvenc_pulseshape *const ps, double hold_time, uint8_t time_unit)
 
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)
 
void sstvenc_ps_advance (struct sstvenc_pulseshape *const ps)
 
void sstvenc_ps_compute (struct sstvenc_pulseshape *const ps)
 
size_t sstvenc_psosc_fill_buffer (struct sstvenc_pulseshape *const ps, struct sstvenc_oscillator *const osc, double *buffer, size_t buffer_sz)
 

Detailed Description

The purpose of this module is to drive the amplitude of an oscillator to ensure the waveform generated contains as few artefacts as possible.


Data Structure Documentation

◆ sstvenc_pulseshape

struct sstvenc_pulseshape

Pulse shaper data structure. This should be initialised by calling sstvenc_ps_init.

Definition at line 89 of file pulseshape.h.

Collaboration diagram for sstvenc_pulseshape:
Data Fields
double amplitude

Peak amplitude of the pulse

uint16_t fall_sz

Number of samples for the falling pulse.

uint32_t hold_sz

Number of samples for the hold phase.

double output

The last computed output of the pulse shaper

uint8_t phase

Current pulse shaper phase.

uint16_t rise_sz

Number of samples for the rising pulse.

uint32_t sample_idx

Sample index for the current phase.

uint32_t sample_rate

Sample rate for the pulse in Hz

Macro Definition Documentation

◆ SSTVENC_PS_HOLD_TIME_INF

#define SSTVENC_PS_HOLD_TIME_INF   SSTVENC_TS_INFINITE

Hold time = infinite.

Definition at line 83 of file pulseshape.h.

Referenced by sstvenc_ps_compute().

Function Documentation

◆ sstvenc_ps_advance()

void sstvenc_ps_advance ( struct sstvenc_pulseshape *const ps)

Advance the pulse shaper to the next phase, regardless of whether it is finished with the present one. A no-op at the "done" phase.

Parameters
[out]psThe pulse shaper being advanced.

Definition at line 56 of file pulseshape.c.

56 {
57 if (ps->phase < SSTVENC_PS_PHASE_DONE) {
58 ps->sample_idx = 0;
59 ps->phase++;
60 }
61}
#define SSTVENC_PS_PHASE_DONE
Definition pulseshape.h:75
uint32_t sample_idx
Definition pulseshape.h:97

References sstvenc_pulseshape::phase, sstvenc_pulseshape::sample_idx, and SSTVENC_PS_PHASE_DONE.

Referenced by sstvenc_modulator_next_hold_sample(), sstvenc_ps_compute(), and sstvenc_sequencer_advance().

Here is the caller graph for this function:

◆ sstvenc_ps_compute()

void sstvenc_ps_compute ( struct sstvenc_pulseshape *const ps)

Compute the next pulse shaper value and store it in the output field. A no-op if the sample rate is set to zero or the pulse shaper is done.

The output envelope amplitude can be read from sstvenc_pulseshape::output.

Parameters
[out]psThe pulse shaper being computed.

Definition at line 63 of file pulseshape.c.

63 {
64 ps->sample_idx++;
65
66 switch (ps->phase) {
68 ps->phase++;
69 /* Fall-thru */
71 if (ps->rise_sz) {
72 /* Compute the raised sine amplitude */
73 ps->output = ps->amplitude
74 * (1.0
75 - cos((ps->sample_idx * M_PI)
76 / (2 * ((double)ps->rise_sz))));
77 if (ps->output > ps->amplitude) {
78 ps->output = ps->amplitude;
79 }
80 }
81 if (ps->sample_idx > ps->rise_sz) {
82 /* Next phase */
84 }
85 break;
87 ps->output = ps->amplitude;
89 && (ps->sample_idx >= ps->hold_sz)) {
90 /* Next phase */
92 }
93 break;
95 if (ps->fall_sz) {
96 /* Compute the raised sine amplitude */
97 ps->output
98 = ps->amplitude
99 * (1.0
100 - cos(((ps->fall_sz - ps->sample_idx) * M_PI)
101 / (2 * ((double)ps->fall_sz))));
102
103 if (ps->output > ps->amplitude) {
104 ps->output = ps->amplitude;
105 }
106 }
107 if (ps->sample_idx >= ps->fall_sz) {
108 /* Next phase */
110 }
111 break;
113 default:
114 ps->output = 0.0;
115 break;
116 }
117}
#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_HOLD_TIME_INF
Definition pulseshape.h:83
void sstvenc_ps_advance(struct sstvenc_pulseshape *const ps)
Definition pulseshape.c:56

References sstvenc_pulseshape::amplitude, sstvenc_pulseshape::fall_sz, sstvenc_pulseshape::hold_sz, sstvenc_pulseshape::output, sstvenc_pulseshape::phase, sstvenc_pulseshape::rise_sz, sstvenc_pulseshape::sample_idx, sstvenc_ps_advance(), SSTVENC_PS_HOLD_TIME_INF, SSTVENC_PS_PHASE_DONE, SSTVENC_PS_PHASE_FALL, SSTVENC_PS_PHASE_HOLD, SSTVENC_PS_PHASE_INIT, and SSTVENC_PS_PHASE_RISE.

Referenced by sstvenc_cw_handle_state_dahspace(), sstvenc_cw_handle_state_ditspace(), sstvenc_cw_handle_state_mark(), sstvenc_modulator_next_fall_sample(), sstvenc_modulator_next_hold_sample(), sstvenc_modulator_next_rise_sample(), sstvenc_psosc_fill_buffer(), and sstvenc_sequencer_compute().

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

◆ sstvenc_ps_init()

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 )

Initialise a pulse shaper.

Parameters
[out]psThe pulse shaper being initialised
[in]amplitudeThe peak amplitude for the pulse shaper
[in]rise_timeThe rise time in seconds, use 0 to disable rise.
[in]hold_timeThe hold time in seconds, use INFINITY for an indefinite hold.
[in]fall_timeThe fall time in seconds, use 0 to disable fall.
[in]sample_rateThe sample rate in Hz.
[in]time_unitThe time unit used to measure rise_time, hold_time and fall_time.

Definition at line 28 of file pulseshape.c.

30 {
31 uint32_t samples;
32
33 ps->amplitude = amplitude;
34 ps->sample_rate = sample_rate;
35 ps->output = 0.0;
36
37 samples
38 = sstvenc_ts_unit_to_samples(rise_time, sample_rate, time_unit);
39 if (samples > UINT16_MAX) {
40 ps->rise_sz = UINT16_MAX;
41 } else {
42 ps->rise_sz = samples;
43 }
44
45 samples
46 = sstvenc_ts_unit_to_samples(fall_time, sample_rate, time_unit);
47 if (samples > UINT16_MAX) {
48 ps->fall_sz = UINT16_MAX;
49 } else {
50 ps->fall_sz = samples;
51 }
52
53 sstvenc_ps_reset(ps, hold_time, time_unit);
54}
uint32_t sample_rate
Definition pulseshape.h:95
void sstvenc_ps_reset(struct sstvenc_pulseshape *const ps, double hold_time, uint8_t time_unit)
Definition pulseshape.c:21
uint32_t sstvenc_ts_unit_to_samples(double time, uint32_t sample_rate, uint8_t unit)
Definition timescale.c:46

References sstvenc_pulseshape::amplitude, sstvenc_pulseshape::fall_sz, sstvenc_pulseshape::output, sstvenc_pulseshape::rise_sz, sstvenc_pulseshape::sample_rate, sstvenc_ps_reset(), and sstvenc_ts_unit_to_samples().

Referenced by sstvenc_cw_init(), sstvenc_modulator_init(), and sstvenc_sequencer_begin_tone().

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

◆ sstvenc_ps_reset()

void sstvenc_ps_reset ( struct sstvenc_pulseshape *const ps,
double hold_time,
uint8_t time_unit )

Reset the pulse shape state machine with a new hold time, but otherwise identical settings.

Parameters
[in,out]psPulse shaper context being reset
[in]hold_timeNew hold time given in the time unit specified by time_unit.
[in]time_unitTime unit used to measure hold_time. Must be one of the values given in Time-scale units

Definition at line 21 of file pulseshape.c.

22 {
23 uint32_t samples = sstvenc_ts_unit_to_samples(
24 hold_time, ps->sample_rate, time_unit);
25 sstvenc_ps_reset_samples(ps, samples);
26}
void sstvenc_ps_reset_samples(struct sstvenc_pulseshape *const ps, uint32_t hold_time)
Definition pulseshape.c:14

References sstvenc_pulseshape::sample_rate, sstvenc_ps_reset_samples(), and sstvenc_ts_unit_to_samples().

Referenced by sstvenc_cw_end_subsym(), sstvenc_cw_end_symbol(), and sstvenc_ps_init().

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

◆ sstvenc_ps_reset_samples()

void sstvenc_ps_reset_samples ( struct sstvenc_pulseshape *const ps,
uint32_t hold_time )

Reset the pulse shape state machine with a new hold time given in samples, but otherwise identical settings.

Parameters
[in,out]psPulse shaper context being reset
[in]hold_timeNew hold time (given as number of samples).

Definition at line 14 of file pulseshape.c.

15 {
17 ps->hold_sz = hold_time;
18 ps->sample_idx = 0;
19}

References sstvenc_pulseshape::hold_sz, sstvenc_pulseshape::phase, sstvenc_pulseshape::sample_idx, and SSTVENC_PS_PHASE_INIT.

Referenced by sstvenc_cw_start_mark(), and sstvenc_ps_reset().

Here is the caller graph for this function:

◆ sstvenc_psosc_fill_buffer()

size_t sstvenc_psosc_fill_buffer ( struct sstvenc_pulseshape *const ps,
struct sstvenc_oscillator *const osc,
double * buffer,
size_t buffer_sz )

Fill the given buffer with audio samples from the oscillator shaped with the given pulse shaper. Stop if we run out of buffer space or if the pulse shaper state machine finishes. Return the number of samples generated.

Parameters
[in,out]psPulse shaper state machine to pull envelope samples from.
[in,out]oscSine wave oscillator. Its amplitude will be modulated by the pulse shaper.
[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 119 of file pulseshape.c.

121 {
122 size_t written_sz = 0;
123
124 while ((buffer_sz > 0) && (ps->phase < SSTVENC_PS_PHASE_DONE)) {
126 osc->amplitude = ps->output;
127
129 buffer[0] = osc->output;
130
131 buffer++;
132 buffer_sz--;
133
134 written_sz++;
135 }
136
137 return written_sz;
138}
void sstvenc_osc_compute(struct sstvenc_oscillator *const osc)
Definition oscillator.c:52
void sstvenc_ps_compute(struct sstvenc_pulseshape *const ps)
Definition pulseshape.c:63

References sstvenc_oscillator::amplitude, sstvenc_oscillator::output, sstvenc_pulseshape::output, sstvenc_pulseshape::phase, sstvenc_osc_compute(), sstvenc_ps_compute(), and SSTVENC_PS_PHASE_DONE.

Here is the call graph for this function: