TinyModem
Header-only software audio modem library
Loading...
Searching...
No Matches
tinymodem::PSKDecoder Class Reference

PSK demodulator (BPSK, QPSK and 8PSK compatible with fldigi): the PCM audio data is written to the decoder and the decoded bytes are written to the output. The input can be 8, 16 or 32 bit signed samples with any number of channels (only PSKConfig::channel is evaluated). More...

#include <PSKDecoder.h>

Inheritance diagram for tinymodem::PSKDecoder:
Collaboration diagram for tinymodem::PSKDecoder:

Public Member Functions

 PSKDecoder ()=default
 PSKDecoder (Print &out)
PSKConfig defaultConfig ()
 Provides a default configuration: psk31.
void setAudioInfo (audio_tools::AudioInfo info) override
 Defines the format of the input audio data.
audio_tools::AudioInfo audioInfo () override
bool begin (PSKConfig config)
 Starts the processing with the indicated configuration.
bool begin () override
void end () override
 Processes the remaining samples and reports the end of the carrier.
void flush () override
 Processes the remaining samples (e.g. at the end of the input).
size_t write (const uint8_t *data, size_t len) override
 Provide PCM data to the decoder.
bool isCarrier () override
 true while a transmission is received
bool isFinished () override
 true if the decoding was stopped (rx_one)
float frequencyOffset ()
 Current frequency offset of the received signal in Hz.
PSKConfig & config ()
 The configuration which was provided in begin().
 operator bool () override
Public Member Functions inherited from tinymodem::ModemDecoder
void setStatusOutput (Print &out)
 Defines the output for the ### CARRIER / ### NOCARRIER messages.
void setQuiet (bool quiet)
 Suppresses the status messages.
const char * mime () override

Protected Member Functions

void resetState ()
void setFrequencyOffset (float offset)
float noise ()
 uniform random value in the range -0.5 to 0.5
void addSample (float x, bool add_noise)
void recalculate ()
 Avoids the accumulation of rounding errors.
void updateTiming ()
 The decision time is the circular center of the energy distribution.
int positions ()
 number of phase positions
void decide ()
 Bit decision from the phase difference to the previous symbol.
void mfskVaricode (int bit)
 MFSK Varicode (8PSK): a character ends with "001".
void releaseHeld ()
void output (uint8_t ch)
void varicode (int bit)
 Collects the bits of a character: characters are separated by "00".
void startOfCarrier (float amplitude)
void endOfCarrier ()
Protected Member Functions inherited from tinymodem::ModemDecoder
void status (const char *fmt,...)

Protected Attributes

PSKConfig cfg
bool is_active = false
bool is_finished = false
PcmInput input
uint32_t noise_seed = 1
float samples_per_symbol = 0
int window = 0
float nco_re = 1
float nco_im = 0
float step_re = 1
float step_im = 0
float freq_offset = 0
audio_tools::Vector< float > history
int pos = 0
float sum_i = 0
float sum_q = 0
float sum_power = 0
uint32_t sample_count = 0
float phase = 0
float target = 0.5f
float countdown = 0
float bin_sum [BINS]
int bin_count [BINS]
float hist [BINS]
float prev_i = 0
float prev_q = 0
float quality = 0
float quality_m = 0
bool carrier = false
int zeros = 0
int ones = 0
int weak = 0
int last_bit = 1
uint16_t code = 0
QPSKCode qpsk
uint32_t mfsk_code = 0
uint8_t held [MAX_ONES]
int nheld = 0
float track_amplitude = 0
unsigned ndata = 0
unsigned nsymbols = 0
float quality_total = 0
float amplitude_total = 0
Protected Attributes inherited from tinymodem::ModemDecoder
Print * p_status = nullptr
bool is_quiet = false

Static Protected Attributes

static constexpr int BINS = 16
static constexpr int MIN_PREAMBLE = 8
static constexpr int MAX_ONES = 20
static constexpr int MAX_WEAK = 3
 the signal is lost after MAX_WEAK symbols below LOST_LEVEL
static constexpr float LOST_LEVEL = 0.3f
static constexpr float AFC_GAIN = 0.1f
static constexpr float TIMING_SMOOTHING = 0.15f
static constexpr float TIMING_GAIN = 0.5f
static constexpr float MAX_CORRECTION = 0.125f

Detailed Description

PSK demodulator (BPSK, QPSK and 8PSK compatible with fldigi): the PCM audio data is written to the decoder and the decoded bytes are written to the output. The input can be 8, 16 or 32 bit signed samples with any number of channels (only PSKConfig::channel is evaluated).

The signal is mixed to the baseband and integrated over one symbol. The symbol timing is determined from the energy distribution over the symbol period, the bits from the phase difference of consecutive symbols: QPSK uses a soft decision Viterbi decoder. An automatic frequency control tracks frequency offsets of up to a quarter of the symbol rate (QPSK: 1/8, 8PSK: 1/16). The receiver starts with a run of phase reversals (preamble) and stops when the signal is lost or with a long steady carrier (postamble of BPSK and 8PSK).

Constructor & Destructor Documentation

◆ PSKDecoder() [1/2]

tinymodem::PSKDecoder::PSKDecoder ( )
default

◆ PSKDecoder() [2/2]

tinymodem::PSKDecoder::PSKDecoder ( Print & out)
inline

Member Function Documentation

◆ addSample()

void tinymodem::PSKDecoder::addSample ( float x,
bool add_noise )
inlineprotected

◆ audioInfo()

audio_tools::AudioInfo tinymodem::PSKDecoder::audioInfo ( )
inlineoverride

◆ begin() [1/2]

bool tinymodem::PSKDecoder::begin ( )
inlineoverride

◆ begin() [2/2]

bool tinymodem::PSKDecoder::begin ( PSKConfig config)
inline

Starts the processing with the indicated configuration.

◆ config()

PSKConfig & tinymodem::PSKDecoder::config ( )
inline

The configuration which was provided in begin().

◆ decide()

void tinymodem::PSKDecoder::decide ( )
inlineprotected

Bit decision from the phase difference to the previous symbol.

◆ defaultConfig()

PSKConfig tinymodem::PSKDecoder::defaultConfig ( )
inline

Provides a default configuration: psk31.

◆ end()

void tinymodem::PSKDecoder::end ( )
inlineoverride

Processes the remaining samples and reports the end of the carrier.

◆ endOfCarrier()

void tinymodem::PSKDecoder::endOfCarrier ( )
inlineprotected

◆ flush()

void tinymodem::PSKDecoder::flush ( )
inlineoverridevirtual

Processes the remaining samples (e.g. at the end of the input).

Implements tinymodem::ModemDecoder.

◆ frequencyOffset()

float tinymodem::PSKDecoder::frequencyOffset ( )
inline

Current frequency offset of the received signal in Hz.

◆ isCarrier()

bool tinymodem::PSKDecoder::isCarrier ( )
inlineoverridevirtual

true while a transmission is received

Implements tinymodem::ModemDecoder.

◆ isFinished()

bool tinymodem::PSKDecoder::isFinished ( )
inlineoverridevirtual

true if the decoding was stopped (rx_one)

Implements tinymodem::ModemDecoder.

◆ mfskVaricode()

void tinymodem::PSKDecoder::mfskVaricode ( int bit)
inlineprotected

MFSK Varicode (8PSK): a character ends with "001".

◆ noise()

float tinymodem::PSKDecoder::noise ( )
inlineprotected

uniform random value in the range -0.5 to 0.5

◆ operator bool()

tinymodem::PSKDecoder::operator bool ( )
inlineoverride

◆ output()

void tinymodem::PSKDecoder::output ( uint8_t ch)
inlineprotected

◆ positions()

int tinymodem::PSKDecoder::positions ( )
inlineprotected

number of phase positions

◆ recalculate()

void tinymodem::PSKDecoder::recalculate ( )
inlineprotected

Avoids the accumulation of rounding errors.

◆ releaseHeld()

void tinymodem::PSKDecoder::releaseHeld ( )
inlineprotected

◆ resetState()

void tinymodem::PSKDecoder::resetState ( )
inlineprotected

◆ setAudioInfo()

void tinymodem::PSKDecoder::setAudioInfo ( audio_tools::AudioInfo info)
inlineoverride

Defines the format of the input audio data.

◆ setFrequencyOffset()

void tinymodem::PSKDecoder::setFrequencyOffset ( float offset)
inlineprotected

◆ startOfCarrier()

void tinymodem::PSKDecoder::startOfCarrier ( float amplitude)
inlineprotected

◆ updateTiming()

void tinymodem::PSKDecoder::updateTiming ( )
inlineprotected

The decision time is the circular center of the energy distribution.

◆ varicode()

void tinymodem::PSKDecoder::varicode ( int bit)
inlineprotected

Collects the bits of a character: characters are separated by "00".

◆ write()

size_t tinymodem::PSKDecoder::write ( const uint8_t * data,
size_t len )
inlineoverride

Provide PCM data to the decoder.

Member Data Documentation

◆ AFC_GAIN

float tinymodem::PSKDecoder::AFC_GAIN = 0.1f
staticconstexprprotected

◆ amplitude_total

float tinymodem::PSKDecoder::amplitude_total = 0
protected

◆ bin_count

int tinymodem::PSKDecoder::bin_count[BINS]
protected

◆ bin_sum

float tinymodem::PSKDecoder::bin_sum[BINS]
protected

◆ BINS

int tinymodem::PSKDecoder::BINS = 16
staticconstexprprotected

◆ carrier

bool tinymodem::PSKDecoder::carrier = false
protected

◆ cfg

PSKConfig tinymodem::PSKDecoder::cfg
protected

◆ code

uint16_t tinymodem::PSKDecoder::code = 0
protected

◆ countdown

float tinymodem::PSKDecoder::countdown = 0
protected

◆ freq_offset

float tinymodem::PSKDecoder::freq_offset = 0
protected

◆ held

uint8_t tinymodem::PSKDecoder::held[MAX_ONES]
protected

◆ hist

float tinymodem::PSKDecoder::hist[BINS]
protected

◆ history

audio_tools::Vector<float> tinymodem::PSKDecoder::history
protected

◆ input

PcmInput tinymodem::PSKDecoder::input
protected

◆ is_active

bool tinymodem::PSKDecoder::is_active = false
protected

◆ is_finished

bool tinymodem::PSKDecoder::is_finished = false
protected

◆ last_bit

int tinymodem::PSKDecoder::last_bit = 1
protected

◆ LOST_LEVEL

float tinymodem::PSKDecoder::LOST_LEVEL = 0.3f
staticconstexprprotected

◆ MAX_CORRECTION

float tinymodem::PSKDecoder::MAX_CORRECTION = 0.125f
staticconstexprprotected

◆ MAX_ONES

int tinymodem::PSKDecoder::MAX_ONES = 20
staticconstexprprotected

◆ MAX_WEAK

int tinymodem::PSKDecoder::MAX_WEAK = 3
staticconstexprprotected

the signal is lost after MAX_WEAK symbols below LOST_LEVEL

◆ mfsk_code

uint32_t tinymodem::PSKDecoder::mfsk_code = 0
protected

◆ MIN_PREAMBLE

int tinymodem::PSKDecoder::MIN_PREAMBLE = 8
staticconstexprprotected

◆ nco_im

float tinymodem::PSKDecoder::nco_im = 0
protected

◆ nco_re

float tinymodem::PSKDecoder::nco_re = 1
protected

◆ ndata

unsigned tinymodem::PSKDecoder::ndata = 0
protected

◆ nheld

int tinymodem::PSKDecoder::nheld = 0
protected

◆ noise_seed

uint32_t tinymodem::PSKDecoder::noise_seed = 1
protected

◆ nsymbols

unsigned tinymodem::PSKDecoder::nsymbols = 0
protected

◆ ones

int tinymodem::PSKDecoder::ones = 0
protected

◆ phase

float tinymodem::PSKDecoder::phase = 0
protected

◆ pos

int tinymodem::PSKDecoder::pos = 0
protected

◆ prev_i

float tinymodem::PSKDecoder::prev_i = 0
protected

◆ prev_q

float tinymodem::PSKDecoder::prev_q = 0
protected

◆ qpsk

QPSKCode tinymodem::PSKDecoder::qpsk
protected

◆ quality

float tinymodem::PSKDecoder::quality = 0
protected

◆ quality_m

float tinymodem::PSKDecoder::quality_m = 0
protected

◆ quality_total

float tinymodem::PSKDecoder::quality_total = 0
protected

◆ sample_count

uint32_t tinymodem::PSKDecoder::sample_count = 0
protected

◆ samples_per_symbol

float tinymodem::PSKDecoder::samples_per_symbol = 0
protected

◆ step_im

float tinymodem::PSKDecoder::step_im = 0
protected

◆ step_re

float tinymodem::PSKDecoder::step_re = 1
protected

◆ sum_i

float tinymodem::PSKDecoder::sum_i = 0
protected

◆ sum_power

float tinymodem::PSKDecoder::sum_power = 0
protected

◆ sum_q

float tinymodem::PSKDecoder::sum_q = 0
protected

◆ target

float tinymodem::PSKDecoder::target = 0.5f
protected

◆ TIMING_GAIN

float tinymodem::PSKDecoder::TIMING_GAIN = 0.5f
staticconstexprprotected

◆ TIMING_SMOOTHING

float tinymodem::PSKDecoder::TIMING_SMOOTHING = 0.15f
staticconstexprprotected

◆ track_amplitude

float tinymodem::PSKDecoder::track_amplitude = 0
protected

◆ weak

int tinymodem::PSKDecoder::weak = 0
protected

◆ window

int tinymodem::PSKDecoder::window = 0
protected

◆ zeros

int tinymodem::PSKDecoder::zeros = 0
protected

The documentation for this class was generated from the following file: