|
TinyModem
Header-only software audio modem library
|
Multi-tone FSK demodulator: 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 MFSKConfig::channel is evaluated). More...
#include <MFSKDecoder.h>


Public Member Functions | |
| MFSKDecoder ()=default | |
| MFSKDecoder (Print &out) | |
| MFSKConfig | defaultConfig () |
| Provides a default configuration: mfsk16. | |
| void | setAudioInfo (audio_tools::AudioInfo info) override |
| Defines the format of the input audio data. | |
| audio_tools::AudioInfo | audioInfo () override |
| bool | begin (MFSKConfig 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 all buffered 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) | |
| MFSKConfig & | 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 Types | |
| enum class | State { SEARCH , PREAMBLE , DATA } |
Protected Member Functions | |
| void | tune (float new_scale) |
| void | setupDetector (audio_tools::GoertzelDetector &det, float freq) |
| void | startSearch () |
| Back to the search for the next preamble. | |
| void | resetState () |
| float | noise () |
| uniform random value in the range -0.5 to 0.5 | |
| void | addSample (float sample, bool add_noise) |
| void | discard (size_t n) |
| Removes the processed samples at the start of the buffer. | |
| float | magnitude (int tone, int start) |
| Magnitude (amplitude) of the tone in the window starting at start. | |
| float | magnitude (audio_tools::GoertzelDetector &det, int start) |
| Magnitude (amplitude) of the detector's frequency in the window. | |
| float | windowAmplitude (int start) |
| Amplitude of a sine with the same energy as the window. | |
| bool | step () |
| One processing step: returns false if more data is needed. | |
| bool | searchStep () |
| Searches for the preamble at the start of the buffer. | |
| bool | hasHighTone (float clock_error, float low) |
| bool | acquire (float coarse_error) |
| int | findTiming () |
| bool | estimateClock (int offset) |
| bool | symbolStep () |
| Analyzes the next symbol. | |
| void | preambleSymbol (int symbol, float amplitude, bool strong) |
| void | dataSymbol (int symbol, float amplitude, float second, bool strong, float symbol_nsamples) |
| void | outputSymbol (int symbol) |
| void | startOfCarrier () |
| void | endOfCarrier () |
| Protected Member Functions inherited from tinymodem::ModemDecoder | |
| void | status (const char *fmt,...) |
Protected Attributes | |
| MFSKConfig | cfg |
| bool | is_active = false |
| bool | is_finished = false |
| PcmInput | input |
| audio_tools::Vector< audio_tools::GoertzelDetector > | detectors |
| audio_tools::Vector< audio_tools::GoertzelDetector > | search_detectors |
| audio_tools::Vector< float > | magnitudes |
| audio_tools::Vector< float > | samples |
| size_t | nvalid = 0 |
| size_t | needed = 0 |
| int | ntones = 16 |
| int | bits_per_symbol = 4 |
| float | nsamples = 0 |
| int | window = 0 |
| int | delta = 1 |
| int | acquire_step = 1 |
| int | hop = 1 |
| uint32_t | noise_seed = 1 |
| float | scale = 1.0f |
| frequency scale which results from the different sample rates | |
| float | drift = 0.0f |
| learned timing drift in samples per symbol | |
| bool | estimate_clock = true |
| true if the clock of the sender is determined from the tones | |
| State | state = State::SEARCH |
| float | pos = 0 |
| float | track_amplitude = 0 |
| int | preamble_count = 0 |
| int | sync_stage = 0 |
| bool | has_pending = false |
| int | pending_symbol = 0 |
| uint32_t | bit_buffer = 0 |
| int | bit_count = 0 |
| unsigned | ndata = 0 |
| unsigned | nsymbols = 0 |
| float | confidence_total = 0 |
| float | amplitude_total = 0 |
| double | data_nsamples = 0 |
| Protected Attributes inherited from tinymodem::ModemDecoder | |
| Print * | p_status = nullptr |
| bool | is_quiet = false |
Static Protected Attributes | |
| static constexpr int | ACQUIRE_SYMBOLS = 4 |
| number of preamble symbols which are used for the timing acquisition | |
| static constexpr int | MAX_PREAMBLE = 64 |
| max number of preamble symbols before we give up | |
| static constexpr float | MAX_CLOCK_ERROR = 0.03f |
| max difference of the sample rates of sender and receiver | |
| static constexpr float | CLOCK_ERROR_STEP = 0.001f |
| static constexpr float | MIN_CLOCK_GAIN = 1.2f |
| a different clock must provide this much more energy | |
| static constexpr float | TIMING_GAIN = 0.25f |
| gains of the timing loop | |
| static constexpr float | DRIFT_GAIN = 0.05f |
| static constexpr float | LOST_LEVEL = 0.4f |
| a symbol below this part of the tracked amplitude is lost | |
| static constexpr float | NEW_SIGNAL_LEVEL = 4.0f |
| static constexpr float | CLEAR_RATIO = 1.5f |
| static constexpr float | HIGH_TONE_LEVEL = 0.25f |
| static constexpr float | MAX_CONFIDENCE = 100.0f |
| the confidence of a symbol is limited to this value | |
| static constexpr int | SEARCH_STEPS = 3 |
| the search checks the clock errors -3% to +3% in steps of 1% | |
| static constexpr float | SEARCH_STEP = 0.01f |
Multi-tone FSK demodulator: 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 MFSKConfig::channel is evaluated).
The decoder searches for the preamble, determines the symbol timing from the alternating preamble tones and waits for the sync symbols. Then each symbol is analyzed with one Goertzel filter per tone. The timing is tracked with an early/late gate, so small differences of the sample rates are corrected. The end of a transmission is detected when the signal is lost.
Status messages (### CARRIER and ### NOCARRIER) are written to the status output.
|
strongprotected |
|
default |
|
inline |
|
inlineprotected |
Determines the symbol timing and the clock of the sender from the alternating preamble tones: the coarse clock error is known from the search
|
inlineprotected |
|
inlineoverride |
|
inlineoverride |
|
inline |
Starts the processing with the indicated configuration.
|
inline |
The configuration which was provided in begin().
|
inlineprotected |
|
inline |
Provides a default configuration: mfsk16.
|
inlineprotected |
Removes the processed samples at the start of the buffer.
|
inlineoverride |
Processes the remaining samples and reports the end of the carrier.
|
inlineprotected |
|
inlineprotected |
Determines the exact frequency scale from the highest preamble tone and adapts the receiver to it: returns true if the receiver was retuned
|
inlineprotected |
Finds the offset where the preamble tones are best separated: returns -1 if there is no signal
|
inlineoverridevirtual |
Processes all buffered samples (e.g. at the end of the input).
Implements tinymodem::ModemDecoder.
|
inlineprotected |
Quick check before the (expensive) acquisition: the preamble alternates the lowest and the highest tone, so the highest tone must be present in one of the next symbols. This rejects a steady tone (e.g. a carrier at the lowest tone), which would otherwise start an acquisition at each step.
|
inlineoverridevirtual |
true while a transmission is received
Implements tinymodem::ModemDecoder.
|
inlineoverridevirtual |
true if the decoding was stopped (rx_one)
Implements tinymodem::ModemDecoder.
|
inlineprotected |
Magnitude (amplitude) of the detector's frequency in the window.
|
inlineprotected |
Magnitude (amplitude) of the tone in the window starting at start.
|
inlineprotected |
uniform random value in the range -0.5 to 0.5
|
inlineoverride |
|
inlineprotected |
|
inlineprotected |
|
inlineprotected |
|
inlineprotected |
Searches for the preamble at the start of the buffer.
|
inlineoverride |
Defines the format of the input audio data.
|
inlineprotected |
|
inlineprotected |
|
inlineprotected |
Back to the search for the next preamble.
|
inlineprotected |
One processing step: returns false if more data is needed.
|
inlineprotected |
Analyzes the next symbol.
|
inlineprotected |
Adapts the tones and the symbol length to the clock of the sender: a sender with a faster sample rate results in lower frequencies (scale < 1.0) and longer symbols.
|
inlineprotected |
Amplitude of a sine with the same energy as the window.
|
inlineoverride |
Provide PCM data to the decoder.
|
protected |
|
staticconstexprprotected |
number of preamble symbols which are used for the timing acquisition
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
staticconstexprprotected |
the tone of a preamble or sync symbol must be this much stronger than any other tone
|
staticconstexprprotected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
learned timing drift in samples per symbol
|
staticconstexprprotected |
|
protected |
true if the clock of the sender is determined from the tones
|
protected |
|
staticconstexprprotected |
the highest preamble tone must have this part of the lowest tone's amplitude (a window may only partly overlap a symbol)
|
protected |
|
protected |
|
protected |
|
protected |
|
staticconstexprprotected |
a symbol below this part of the tracked amplitude is lost
|
protected |
|
staticconstexprprotected |
max difference of the sample rates of sender and receiver
|
staticconstexprprotected |
the confidence of a symbol is limited to this value
|
staticconstexprprotected |
max number of preamble symbols before we give up
|
staticconstexprprotected |
a different clock must provide this much more energy
|
protected |
|
protected |
|
staticconstexprprotected |
a preamble symbol above this multiple of the tracked amplitude starts a new search
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
frequency scale which results from the different sample rates
|
protected |
|
staticconstexprprotected |
|
staticconstexprprotected |
the search checks the clock errors -3% to +3% in steps of 1%
|
protected |
|
protected |
|
staticconstexprprotected |
gains of the timing loop
|
protected |
|
protected |