libsstvenc
Asynchronous Analogue SSTV encoder
Loading...
Searching...
No Matches
Oscillator implementation

Data Structures

struct  sstvenc_oscillator
 

Macros

#define SSTVENC_OSC_PHASE_FRAC_BITS   (29)
 
#define SSTVENC_OSC_PHASE_FRAC_SCALE    ((double)(1 << SSTVENC_OSC_PHASE_FRAC_BITS))
 

Functions

double sstvenc_osc_get_frequency (const struct sstvenc_oscillator *const osc)
 
void sstvenc_osc_set_frequency (struct sstvenc_oscillator *const osc, double frequency)
 
void sstvenc_osc_init (struct sstvenc_oscillator *const osc, double amplitude, double frequency, double offset, uint32_t sample_rate)
 
void sstvenc_osc_compute (struct sstvenc_oscillator *const osc)
 

Detailed Description

This is a simple module that can be used to produce a single sinusoid tone at a given frequency for a given sample rate.

The phase is computed at each sample step, and increments modulo 2-Pi. Frequency, amplitude and phase can be modified at any time, they take effect on the next call to sstvenc_osc_compute.


Data Structure Documentation

◆ sstvenc_oscillator

struct sstvenc_oscillator

Oscillator data structure. This must remain allocated for the lifetime of the sinusoid.

Use sstvenc_osc_init to initialise this structure.

Definition at line 29 of file oscillator.h.

Collaboration diagram for sstvenc_oscillator:
Data Fields
double amplitude

The amplitude of the sinusoid: range 0-1.0.

This may be adjusted to ampiltude-modulate the oscillator. The new amplitude takes effect on the next call to sstvenc_osc_compute.

double offset

Phase offset in radians: range 0-2*M_PI.

This may be adjusted to phase-modulate the oscillator. The new phase offset takes effect on the next call to sstvenc_osc_compute.

double output

The last computed output of the sinusoid. The audio output should be read from this field.

uint32_t phase

Fixed-point phase of the sinusoid oscillator. Do not manipulate directly, use sstvenc_osc_init or sstvenc_osc_compute to update. If just re-starting a sine with identical settings, you may set this to 0.

uint32_t phase_inc

Fixed-point phase increment each iteration. Use sstvenc_osc_set_frequency to adjust this or sstvenc_osc_get_frequency to convert back to a frequency in Hz.

uint32_t sample_rate

Sample rate for the sinusoid in Hz. Must not be changed after initialisation.

Macro Definition Documentation

◆ SSTVENC_OSC_PHASE_FRAC_BITS

#define SSTVENC_OSC_PHASE_FRAC_BITS   (29)

Fixed-point phase bit allocation. For a uint32_t, this gives us a range of 0-7.999 with a precision of ~1.86 nano-radians.

Definition at line 20 of file oscillator.c.

◆ SSTVENC_OSC_PHASE_FRAC_SCALE

#define SSTVENC_OSC_PHASE_FRAC_SCALE    ((double)(1 << SSTVENC_OSC_PHASE_FRAC_BITS))

Fixed-point scaling factor, computed from the number of bits.

Definition at line 25 of file oscillator.c.

25#define SSTVENC_OSC_PHASE_FRAC_SCALE \
26 ((double)(1 << SSTVENC_OSC_PHASE_FRAC_BITS))

Referenced by sstvenc_osc_compute(), sstvenc_osc_get_frequency(), and sstvenc_osc_set_frequency().

Function Documentation

◆ sstvenc_osc_compute()

void sstvenc_osc_compute ( struct sstvenc_oscillator *const osc)

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

The next sample is made available in sstvenc_oscillator::output.

Parameters
[in,out]oscOscillator context being computed.

Definition at line 52 of file oscillator.c.

52 {
53 if (osc->sample_rate) {
54 /* Compute output */
55 osc->output = osc->amplitude
56 * sin(osc->offset
57 + (((double)osc->phase)
59
60 /* Increment phase, modulo 2Pi */
61 osc->phase += osc->phase_inc;
62 osc->phase
63 %= (uint32_t)(2 * M_PI * SSTVENC_OSC_PHASE_FRAC_SCALE);
64 }
65}
uint32_t sample_rate
Definition oscillator.h:55
#define SSTVENC_OSC_PHASE_FRAC_SCALE
Definition oscillator.c:25

References sstvenc_oscillator::amplitude, sstvenc_oscillator::offset, sstvenc_oscillator::output, sstvenc_oscillator::phase, sstvenc_oscillator::phase_inc, sstvenc_oscillator::sample_rate, and SSTVENC_OSC_PHASE_FRAC_SCALE.

Referenced by 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 caller graph for this function:

◆ sstvenc_osc_get_frequency()

double sstvenc_osc_get_frequency ( const struct sstvenc_oscillator *const osc)

Get the oscillator frequency in Hertz.

Parameters
[in]oscOscillator context.
Returns
The oscillator frequency in Hertz.

Definition at line 28 of file oscillator.c.

28 {
29 return ((double)(((uint64_t)osc->phase_inc) * osc->sample_rate))
30 / (2 * M_PI * SSTVENC_OSC_PHASE_FRAC_SCALE);
31}

References sstvenc_oscillator::phase_inc, sstvenc_oscillator::sample_rate, and SSTVENC_OSC_PHASE_FRAC_SCALE.

◆ sstvenc_osc_init()

void sstvenc_osc_init ( struct sstvenc_oscillator *const osc,
double amplitude,
double frequency,
double offset,
uint32_t sample_rate )

Initialise an oscillator with the given amplitude, frequency and phase offset. Use this when starting a new sinusoid.

Parameters
[in,out]oscOscillator context being initialised.
[in]amplitudeStarting oscillator amplitude (range 0.0-1.0).
[in]frequencyStarting frequency of the oscillator (range 0.0 - ½ of sample_rate).
[in]offsetStarting phase offset in radians.
[in]sample_rateOutput sample rate in hertz.

Definition at line 42 of file oscillator.c.

43 {
44 osc->amplitude = amplitude;
45 osc->offset = offset;
46 osc->output = 0.0;
47 osc->sample_rate = sample_rate;
48 osc->phase = 0;
49 sstvenc_osc_set_frequency(osc, frequency);
50}
void sstvenc_osc_set_frequency(struct sstvenc_oscillator *const osc, double frequency)
Definition oscillator.c:33

References sstvenc_oscillator::amplitude, sstvenc_oscillator::offset, sstvenc_oscillator::output, sstvenc_oscillator::phase, sstvenc_oscillator::sample_rate, and sstvenc_osc_set_frequency().

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_osc_set_frequency()

void sstvenc_osc_set_frequency ( struct sstvenc_oscillator *const osc,
double frequency )

Set the oscillator frequency in Hertz.

Parameters
[in,out]oscOscillator context being updated.
[in]frequencyThe frequency in Hertz. This MUST be at least 0Hz and less than the nyquist frequency (half the sample rate).

Definition at line 33 of file oscillator.c.

34 {
35 assert(frequency >= 0);
36 assert(frequency < (osc->sample_rate / 2));
37
38 osc->phase_inc = (2 * M_PI * frequency * SSTVENC_OSC_PHASE_FRAC_SCALE)
39 / osc->sample_rate;
40}

References sstvenc_oscillator::phase_inc, sstvenc_oscillator::sample_rate, and SSTVENC_OSC_PHASE_FRAC_SCALE.

Referenced by sstvenc_modulator_next_tone(), sstvenc_osc_init(), and sstvenc_sequencer_begin_tone().

Here is the caller graph for this function: