7#include "AudioTools/CoreAudio/Analysis/GoerzelStream.h"
45 if (info.sample_rate ==
cfg.sample_rate && info.channels ==
cfg.channels &&
46 info.bits_per_sample ==
cfg.bits_per_sample)
48 cfg.sample_rate = info.sample_rate;
49 cfg.channels = info.channels;
50 cfg.bits_per_sample = info.bits_per_sample;
56 using audio_tools::AudioDecoder::begin;
66 if (!
cfg.isValid())
return false;
114 size_t write(
const uint8_t* data,
size_t len)
override {
116 input.write(data, len, [
this](
float sample) {
addSample(sample,
true); });
166 audio_tools::Vector<audio_tools::GoertzelDetector>
detectors;
216 for (
int j = 0; j <
ntones; j++)
221 audio_tools::GoertzelConfig gcfg;
222 gcfg.sample_rate =
cfg.sample_rate;
224 gcfg.target_frequency = freq;
247 return ((
noise_seed >> 8) & 0xFFFF) / 65535.0f - 0.5f;
252 if (add_noise &&
cfg.rx_noise != 0.0f)
253 sample +=
noise() *
cfg.rx_noise * 2.0f;
267 (
nvalid - n) *
sizeof(
float));
278 float magnitude(audio_tools::GoertzelDetector& det,
int start) {
280 const float* data =
samples.data() + start;
281 for (
int j = 0; j <
window; j++) det.processSample(data[j]);
282 return det.getMagnitude() * 2.0f /
window;
287 const float* data =
samples.data() + start;
289 for (
int j = 0; j <
window; j++) sum += data[j] * data[j];
290 return sqrtf(2.0f * sum /
window);
307 if (rms_amplitude <
cfg.min_amplitude) {
312 float best = 0, best_error = 0, nominal = 0;
324 if (best >=
cfg.min_amplitude && best > 0.5f * rms_amplitude &&
341 audio_tools::GoertzelDetector det;
354 if (coarse_error != 0.0f)
tune(1.0f + coarse_error);
365 float amplitude = 0, other = 0;
368 int start = lroundf(offset + k *
nsamples);
371 int tone = a0 > a1 ? 0 : 1;
377 amplitude += a0 > a1 ? a0 : a1;
378 other += a0 > a1 ? a1 : a0;
382 if (amplitude < cfg.min_amplitude || other > 0.5f * amplitude) {
395 int best_offset = -1;
396 float best_score = 0;
400 int start = lroundf(offset + k *
nsamples);
403 if (score > best_score) {
405 best_offset = offset;
419 starts[k] = lroundf(offset + k *
nsamples);
421 if (low[k] > max_low) max_low = low[k];
423 audio_tools::GoertzelDetector det;
424 float high =
cfg.toneFrequency(
ntones - 1);
425 float current_error =
scale - 1.0f;
426 float best_error = current_error, best_mag = -1, current_mag = 0;
430 bool is_current =
step == steps + 1;
435 if (low[k] < 0.5f * max_low) sum +=
magnitude(det, starts[k]);
438 }
else if (sum > best_mag) {
445 tune(1.0f + best_error);
451 int p = lroundf(
pos);
461 for (
int j = 0; j <
ntones; j++) {
466 for (
int j = 0; j <
ntones; j++)
469 bool strong = amplitude >=
cfg.min_amplitude &&
477 float correction =
drift;
481 if (early + late > 0) {
482 float tau = (
window -
delta) * (late - early) / (late + early);
500 int keep_from = lroundf(
pos) -
delta;
502 if (keep_from > 0)
discard(keep_from);
525 void dataSymbol(
int symbol,
float amplitude,
float second,
bool strong,
526 float symbol_nsamples) {
543 float confidence = second > 0 ? amplitude / second :
MAX_CONFIDENCE;
557 if (p_print !=
nullptr) p_print->write(
byte);
572 status(
"### CARRIER mfsk%d %.2f baud @ %.1f Hz ###\n",
ntones,
573 (
double)
cfg.symbol_rate, (
double)
cfg.base_freq);
583 "\n### NOCARRIER ndata=%u confidence=%.3f ampl=%.3f bps=%.2f ###\n",
int acquire_step
Definition MFSKDecoder.h:177
void startSearch()
Back to the search for the next preamble.
Definition MFSKDecoder.h:230
float pos
Definition MFSKDecoder.h:189
uint32_t noise_seed
Definition MFSKDecoder.h:179
bool step()
One processing step: returns false if more data is needed.
Definition MFSKDecoder.h:294
void flush() override
Processes all buffered samples (e.g. at the end of the input).
Definition MFSKDecoder.h:101
int hop
Definition MFSKDecoder.h:178
void setAudioInfo(audio_tools::AudioInfo info) override
Defines the format of the input audio data.
Definition MFSKDecoder.h:44
float drift
learned timing drift in samples per symbol
Definition MFSKDecoder.h:183
bool isFinished() override
true if the decoding was stopped (rx_one)
Definition MFSKDecoder.h:124
static constexpr float MAX_CONFIDENCE
the confidence of a symbol is limited to this value
Definition MFSKDecoder.h:157
void dataSymbol(int symbol, float amplitude, float second, bool strong, float symbol_nsamples)
Definition MFSKDecoder.h:525
static constexpr int MAX_PREAMBLE
max number of preamble symbols before we give up
Definition MFSKDecoder.h:136
PcmInput input
Definition MFSKDecoder.h:165
float scale
frequency scale which results from the different sample rates
Definition MFSKDecoder.h:181
bool isCarrier() override
true while a transmission is received
Definition MFSKDecoder.h:121
float magnitude(audio_tools::GoertzelDetector &det, int start)
Magnitude (amplitude) of the detector's frequency in the window.
Definition MFSKDecoder.h:278
static constexpr float HIGH_TONE_LEVEL
Definition MFSKDecoder.h:155
static constexpr float MIN_CLOCK_GAIN
a different clock must provide this much more energy
Definition MFSKDecoder.h:141
static constexpr float CLOCK_ERROR_STEP
Definition MFSKDecoder.h:139
MFSKConfig defaultConfig()
Provides a default configuration: mfsk16.
Definition MFSKDecoder.h:37
static constexpr float NEW_SIGNAL_LEVEL
Definition MFSKDecoder.h:149
size_t write(const uint8_t *data, size_t len) override
Provide PCM data to the decoder.
Definition MFSKDecoder.h:114
int window
Definition MFSKDecoder.h:175
unsigned nsymbols
Definition MFSKDecoder.h:199
void end() override
Processes the remaining samples and reports the end of the carrier.
Definition MFSKDecoder.h:94
void resetState()
Definition MFSKDecoder.h:235
State state
Definition MFSKDecoder.h:188
bool symbolStep()
Analyzes the next symbol.
Definition MFSKDecoder.h:450
static constexpr int SEARCH_STEPS
the search checks the clock errors -3% to +3% in steps of 1%
Definition MFSKDecoder.h:159
int bit_count
Definition MFSKDecoder.h:196
bool estimate_clock
true if the clock of the sender is determined from the tones
Definition MFSKDecoder.h:185
audio_tools::Vector< audio_tools::GoertzelDetector > detectors
Definition MFSKDecoder.h:166
void preambleSymbol(int symbol, float amplitude, bool strong)
Definition MFSKDecoder.h:506
State
Definition MFSKDecoder.h:132
@ SEARCH
Definition MFSKDecoder.h:132
@ PREAMBLE
Definition MFSKDecoder.h:132
@ DATA
Definition MFSKDecoder.h:132
bool is_active
Definition MFSKDecoder.h:163
int preamble_count
Definition MFSKDecoder.h:191
static constexpr float SEARCH_STEP
Definition MFSKDecoder.h:160
float magnitude(int tone, int start)
Magnitude (amplitude) of the tone in the window starting at start.
Definition MFSKDecoder.h:273
bool hasHighTone(float clock_error, float low)
Definition MFSKDecoder.h:340
float confidence_total
Definition MFSKDecoder.h:200
bool searchStep()
Searches for the preamble at the start of the buffer.
Definition MFSKDecoder.h:299
void endOfCarrier()
Definition MFSKDecoder.h:576
static constexpr float CLEAR_RATIO
Definition MFSKDecoder.h:152
int ntones
Definition MFSKDecoder.h:172
bool begin() override
Definition MFSKDecoder.h:64
float noise()
uniform random value in the range -0.5 to 0.5
Definition MFSKDecoder.h:245
uint32_t bit_buffer
Definition MFSKDecoder.h:195
bool has_pending
Definition MFSKDecoder.h:193
bool acquire(float coarse_error)
Definition MFSKDecoder.h:353
MFSKConfig & config()
The configuration which was provided in begin().
Definition MFSKDecoder.h:127
MFSKDecoder(Print &out)
Definition MFSKDecoder.h:34
static constexpr float DRIFT_GAIN
Definition MFSKDecoder.h:144
static constexpr float TIMING_GAIN
gains of the timing loop
Definition MFSKDecoder.h:143
float nsamples
Definition MFSKDecoder.h:174
unsigned ndata
Definition MFSKDecoder.h:198
size_t nvalid
Definition MFSKDecoder.h:170
int bits_per_symbol
Definition MFSKDecoder.h:173
bool estimateClock(int offset)
Definition MFSKDecoder.h:413
double data_nsamples
Definition MFSKDecoder.h:202
size_t needed
Definition MFSKDecoder.h:171
float track_amplitude
Definition MFSKDecoder.h:190
int pending_symbol
Definition MFSKDecoder.h:194
void outputSymbol(int symbol)
Definition MFSKDecoder.h:550
static constexpr float MAX_CLOCK_ERROR
max difference of the sample rates of sender and receiver
Definition MFSKDecoder.h:138
audio_tools::Vector< audio_tools::GoertzelDetector > search_detectors
Definition MFSKDecoder.h:167
int delta
Definition MFSKDecoder.h:176
float amplitude_total
Definition MFSKDecoder.h:201
bool begin(MFSKConfig config)
Starts the processing with the indicated configuration.
Definition MFSKDecoder.h:59
void startOfCarrier()
Definition MFSKDecoder.h:562
void setupDetector(audio_tools::GoertzelDetector &det, float freq)
Definition MFSKDecoder.h:220
int sync_stage
Definition MFSKDecoder.h:192
int findTiming()
Definition MFSKDecoder.h:394
static constexpr float LOST_LEVEL
a symbol below this part of the tracked amplitude is lost
Definition MFSKDecoder.h:146
float windowAmplitude(int start)
Amplitude of a sine with the same energy as the window.
Definition MFSKDecoder.h:286
audio_tools::Vector< float > samples
Definition MFSKDecoder.h:169
void addSample(float sample, bool add_noise)
Definition MFSKDecoder.h:250
audio_tools::AudioInfo audioInfo() override
Definition MFSKDecoder.h:54
void tune(float new_scale)
Definition MFSKDecoder.h:207
void discard(size_t n)
Removes the processed samples at the start of the buffer.
Definition MFSKDecoder.h:263
audio_tools::Vector< float > magnitudes
Definition MFSKDecoder.h:168
bool is_finished
Definition MFSKDecoder.h:164
static constexpr int ACQUIRE_SYMBOLS
number of preamble symbols which are used for the timing acquisition
Definition MFSKDecoder.h:134
MFSKConfig cfg
Definition MFSKDecoder.h:162
Common API of the demodulators (FSKDecoder, MFSKDecoder): PCM audio data is written to the decoder an...
Definition ModemBase.h:344
void status(const char *fmt,...)
Definition ModemBase.h:367
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
unsigned grayDecode(unsigned gray)
Inverse of grayEncode().
Definition MFSKEncoder.h:15
Configuration of the multi-tone FSK modem (MFSKEncoder, MFSKDecoder). Each symbol is one of tones ton...
Definition MFSKConfig.h:23
bool setMode(const char *mode)
Definition MFSKConfig.h:53