41 if (info.sample_rate ==
cfg.sample_rate && info.channels ==
cfg.channels &&
42 info.bits_per_sample ==
cfg.bits_per_sample)
44 cfg.sample_rate = info.sample_rate;
45 cfg.channels = info.channels;
46 cfg.bits_per_sample = info.bits_per_sample;
52 using audio_tools::AudioDecoder::begin;
62 if (!
cfg.isValid())
return false;
67 if (!
fft.begin(
m))
return false;
71 double w = 2.0 * M_PI *
cfg.center_freq /
cfg.sample_rate;
81 for (
int k = 0; k <
m; k++) {
84 double u = (double)k /
m;
85 double ph = 2.0 * M_PI *
n * (0.5 * u * u - 0.5 * u);
101 status(
"### CSS frames=%u errors=%u ###\n", (
unsigned)
frames,
110 size_t len = (size_t)((2.0 *
n + 64) /
cfg.bandwidth *
cfg.sample_rate);
122 size_t write(
const uint8_t*
data,
size_t len)
override {
125 if (
cfg.rx_noise != 0.0f) x +=
noise() *
cfg.rx_noise * 2.0f;
222 return ((
noise_seed >> 8) & 0xFFFF) / 65535.0f - 0.5f;
237 converter.writeComplex(i, q, [
this](
float re,
float im) {
255 double w = -2.0 * M_PI * offset /
m;
256 float rot_re = cos(w), rot_im = sin(w);
257 float c_re = 1, c_im = 0;
258 for (
int k = 0; k <
m; k++) {
263 float y_re = r_re * ch_re - r_im * ch_im;
264 float y_im = r_re * ch_im + r_im * ch_re;
265 fft_re[k] = y_re * c_re - y_im * c_im;
266 fft_im[k] = y_re * c_im + y_im * c_re;
267 float t = c_re * rot_re - c_im * rot_im;
268 c_im = c_re * rot_im + c_im * rot_re;
272 for (
int k = 0; k <
m; k++)
276 float total = 0, best = 0;
277 for (
int k = 0; k <
n; k++) {
286 float mean = (total - best) / (
n - 1);
287 result.
ratio = mean > 0 ? best / mean : 0;
292 int l = (k +
m - 1) %
m, r = (k + 1) %
m;
298 float d1 = a1 / (1.0f - a1), d2 = -a2 / (1.0f - a2);
299 delta = (d1 > 0 && d2 > 0) ? d2 : d1;
300 if (delta > 0.5f) delta = 0.5f;
301 if (delta < -0.5f) delta = -0.5f;
303 result.
pos = result.
bin + delta;
309 while (pos >
n / 2) pos -=
n;
310 while (pos <= -
n / 2) pos +=
n;
331 if (up.
ratio >=
cfg.detect_threshold) {
385 status(
"### CARRIER css sf%d %.0f Hz @ %.1f Hz ###\n",
386 cfg.spreading_factor, (
double)
cfg.bandwidth,
402 if (
nups < 2)
return 0;
403 float sx = 0, sy = 0, sxx = 0, sxy = 0;
404 for (
int j = 0; j <
nups; j++) {
410 float d =
nups * sxx - sx * sx;
411 return d > 0 ? (
nups * sxy - sx * sy) / d : 0;
417 int value = peak.
bin;
436 int sf =
cfg.spreading_factor;
463 if (p_print !=
nullptr) p_print->write(payload,
frame_len);
472 cfg.spreading_factor)
474 float snr = total > 0 ? 10 * log10f(
snr_total / total) : 0;
476 status(
"\n### NOCARRIER ndata=%d corrected=%d snr=%.1f dB ###\n",
479 status(
"\n### NOCARRIER frame error snr=%.1f dB ###\n", (
double)snr);
static constexpr float TRACKING_GAIN
tracking of the remaining offset per symbol
Definition CSSDecoder.h:160
bool begin(CSSConfig config)
Starts the processing with the indicated configuration.
Definition CSSDecoder.h:55
float sync_offset
Definition CSSDecoder.h:200
void sync()
Definition CSSDecoder.h:356
CSSConfig defaultConfig()
Provides a default configuration: css7 (SF 7, 1000 Hz).
Definition CSSDecoder.h:37
CSSDecoder(Print &out)
Definition CSSDecoder.h:34
float frequencyOffset()
Frequency offset of the last frame in Hz.
Definition CSSDecoder.h:144
bool isCarrier() override
true while a frame is received
Definition CSSDecoder.h:132
float snr_total
Definition CSSDecoder.h:204
bool is_active
Definition CSSDecoder.h:177
float drift
Definition CSSDecoder.h:198
float noise()
uniform random value in the range -0.5 to 0.5
Definition CSSDecoder.h:220
audio_tools::Vector< float > fft_re
Definition CSSDecoder.h:187
audio_tools::Vector< float > power
Definition CSSDecoder.h:187
size_t errorCount()
Number of frames which could not be decoded.
Definition CSSDecoder.h:141
State
Definition CSSDecoder.h:152
@ PAYLOAD
Definition CSSDecoder.h:152
@ SYNC
Definition CSSDecoder.h:152
@ HEADER
Definition CSSDecoder.h:152
@ SEARCH
Definition CSSDecoder.h:152
static constexpr int MAX_UPS
max preamble windows for the drift estimation
Definition CSSDecoder.h:166
void endOfCarrier(bool ok, int corrected=0)
Definition CSSDecoder.h:467
bool isFinished() override
true if the decoding was stopped (rx_one)
Definition CSSDecoder.h:135
int n
Definition CSSDecoder.h:181
float signedBin(float pos)
signed value of a bin (-n/2 to n/2)
Definition CSSDecoder.h:308
bool begin() override
Definition CSSDecoder.h:60
int m
Definition CSSDecoder.h:182
float mix_step_im
Definition CSSDecoder.h:185
audio_tools::Vector< float > fft_im
Definition CSSDecoder.h:187
uint32_t mix_count
Definition CSSDecoder.h:186
size_t errors
Definition CSSDecoder.h:205
bool is_finished
Definition CSSDecoder.h:178
size_t frames
Definition CSSDecoder.h:205
int nsymbols
Definition CSSDecoder.h:203
float rate_factor
Definition CSSDecoder.h:199
CSSConfig cfg
Definition CSSDecoder.h:176
static constexpr int OVERSAMPLING
Definition CSSDecoder.h:157
CSSConfig & config()
The configuration which was provided in begin().
Definition CSSDecoder.h:147
audio_tools::Vector< float > chirp_im
Definition CSSDecoder.h:188
void resetState()
Definition CSSDecoder.h:207
SampleRateConverter converter
Definition CSSDecoder.h:184
float mix_step_re
Definition CSSDecoder.h:185
int nups
Definition CSSDecoder.h:197
void end() override
Processes the remaining samples and reports the statistics.
Definition CSSDecoder.h:98
static constexpr int RING
Definition CSSDecoder.h:153
size_t frameCount()
Number of received frames with a correct CRC.
Definition CSSDecoder.h:138
audio_tools::Vector< uint16_t > symbols
Definition CSSDecoder.h:202
int needed
Definition CSSDecoder.h:203
float freq_offset
Definition CSSDecoder.h:201
void addBaseband(float re, float im)
Definition CSSDecoder.h:242
audio_tools::Vector< float > chirp_re
Definition CSSDecoder.h:188
float ups[MAX_UPS]
Definition CSSDecoder.h:196
static constexpr int PREAMBLE_HITS
Definition CSSDecoder.h:158
audio_tools::AudioInfo audioInfo() override
Definition CSSDecoder.h:50
int64_t count
Definition CSSDecoder.h:189
void flush() override
Processes the remaining samples (e.g. at the end of the input).
Definition CSSDecoder.h:107
void processWindow()
Definition CSSDecoder.h:314
audio_tools::Vector< float > ring_re
Definition CSSDecoder.h:187
int candidate
Definition CSSDecoder.h:193
void setAudioInfo(audio_tools::AudioInfo info) override
Defines the format of the input audio data.
Definition CSSDecoder.h:40
void data()
Header and payload symbols.
Definition CSSDecoder.h:415
void addSample(float x)
Mixes a sample to the baseband and resamples it to the bandwidth.
Definition CSSDecoder.h:226
SimpleFFT fft
Definition CSSDecoder.h:183
int64_t next_start
Definition CSSDecoder.h:190
uint32_t noise_seed
Definition CSSDecoder.h:180
State state
Definition CSSDecoder.h:192
int sync_windows
Definition CSSDecoder.h:194
static constexpr float DRIFT_GAIN
tracking of the remaining drift per symbol
Definition CSSDecoder.h:162
audio_tools::Vector< float > ring_im
Definition CSSDecoder.h:187
Peak spectrum(bool up, float offset)
Definition CSSDecoder.h:254
static constexpr float MIN_DRIFT
min drift in bins per symbol for the correction of the sample rate
Definition CSSDecoder.h:164
float mix_re
Definition CSSDecoder.h:185
int frame_len
Definition CSSDecoder.h:203
float estimateDrift()
Change of the preamble peaks per symbol (least squares fit).
Definition CSSDecoder.h:401
void search()
Preamble: the same bin in consecutive windows.
Definition CSSDecoder.h:329
int hits
Definition CSSDecoder.h:193
PcmInput input
Definition CSSDecoder.h:179
float last_up
Definition CSSDecoder.h:195
float mix_im
Definition CSSDecoder.h:185
size_t write(const uint8_t *data, size_t len) override
Provide PCM data to the decoder.
Definition CSSDecoder.h:122
static int symbols(int bytes, int sf)
number of symbols for the indicated number of bytes
Definition CSS.h:157
static constexpr int HEADER_BYTES
Definition CSS.h:154
static int payloadBytes(int len, int ecc)
bytes of the payload code word
Definition CSS.h:160
static void fromSymbols(const uint16_t *symbols, int n, int sf, uint8_t *data, int len)
Converts symbols into bytes.
Definition CSS.h:211
static int decodeHeader(uint8_t *data)
Corrects the header in place: returns the length or -1 if invalid.
Definition CSS.h:169
static int decodePayload(uint8_t *data, int len, int ecc)
Definition CSS.h:187
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
static constexpr int MAX_ECC
Definition ReedSolomon.h:24
Converts the sample rate of a signal with a windowed sinc low pass filter (by default the cut off is ...
Definition DSPUtils.h:15
Radix 2 complex FFT with a precomputed twiddle table.
Definition DSPUtils.h:131
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
Configuration of the chirp spread spectrum modem (CSSEncoder, CSSDecoder), which works like LoRa in t...
Definition CSS.h:31
static constexpr int MAX_FRAME
max payload of a frame
Definition CSS.h:118
Peak of a spectrum.
Definition CSSDecoder.h:169
float ratio
Definition CSSDecoder.h:173
float pos
Definition CSSDecoder.h:171
int bin
Definition CSSDecoder.h:170
float power
Definition CSSDecoder.h:172