#include #include #include #include #include "freq_meas.h" #include "sr_global.h" #include "dsss_demod.h" #include "simulation.h" #include "generated/dsss_gold_code.h" #include "generated/dsss_butter_filter.h" /* Generated CWT wavelet LUT */ extern const float * const dsss_cwt_wavelet_table; struct iir_biquad cwt_filter_bq[DSSS_FILTER_CLEN] = {DSSS_FILTER_COEFF}; float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug); float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx); float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]); float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st); void debug_print_vector(const char *name, size_t len, const float *data, size_t stride, bool index, bool debug); #ifdef SIMULATION void debug_print_vector(const char *name, size_t len, const float *data, size_t stride, bool index, bool debug) { if (!debug) return; if (index) { DEBUG_PRINTN(" %16s [", ""); for (size_t i=0; i 1000) && (sim_pos % DSSS_CORRELATION_LENGTH == DSSS_CORRELATION_LENGTH-1); if (debug) DEBUG_PRINT("Iteration %zd: signal=%f", sim_pos, new_value); #else void dsss_demod_step(struct dsss_demod_state *st, float new_value) { #endif //const float peak_group_threshold = 0.05 * DSSS_CORRELATION_LENGTH; //const float hole_patching_threshold = 0.01 * DSSS_CORRELATION_LENGTH; st->signal[st->signal_wpos] = new_value; st->signal_wpos = (st->signal_wpos + 1) % ARRAY_LENGTH(st->signal); /* use new, incremented wpos for gold_correlate_step as first element of old data in ring buffer */ for (size_t i=0; icorrelation[i][st->correlation_wpos] = gold_correlate_step(i, st->signal, st->signal_wpos, false); debug_print_vector("correlation", DSSS_GOLD_CODE_COUNT, &st->correlation[0][st->correlation_wpos], DSSS_WAVELET_LUT_SIZE, true, debug); st->correlation_wpos = (st->correlation_wpos + 1) % ARRAY_LENGTH(st->correlation[0]); float cwt[DSSS_GOLD_CODE_COUNT]; for (size_t i=0; icorrelation[i], st->correlation_wpos); debug_print_vector("cwt", DSSS_GOLD_CODE_COUNT, cwt, 1, false, debug); float avg[DSSS_GOLD_CODE_COUNT]; for (size_t i=0; icwt_filter[i].st); debug_print_vector("avg", DSSS_GOLD_CODE_COUNT, avg, 1, false, debug); if (record_channel != -1) DEBUG_PRINTN("%f, %f, %f\n", st->correlation[record_channel][st->correlation_wpos], cwt[record_channel], avg[record_channel]); float max_val = st->group.max; int max_ch = st->group.max_ch; int max_idx = st->group.max_idx + 1; bool found = false; for (size_t i=0; i DSSS_THESHOLD_FACTOR) found = true; if (fabs(val) > fabs(max_val)) { max_val = val; max_ch = i; max_idx = st->group.len; } } if (found) { /* Continue ongoing group */ st->group.len++; st->group.max = max_val; st->group.max_ch = max_ch; st->group.max_idx = max_idx; return; } if (st->group.len == 0) /* We're between groups */ return; /* A group ended. Process result. */ if (record_channel == -1) DEBUG_PRINT("GROUP FOUND: %8d len=%3d max=%f ch=%d offx=%d", sim_pos, st->group.len, st->group.max, st->group.max_ch, st->group.max_idx); /* reset grouping state */ st->group.len = 0; st->group.max_idx = 0; st->group.max_ch = 0; st->group.max = 0.0f; } float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]) { float intermediate = x; for (int i=0; i<(order+1)/2; i++) intermediate = run_biquad(intermediate, &q[i], &st[i]); return intermediate; } float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st) { /* direct form 2, see https://en.wikipedia.org/wiki/Digital_biquad_filter */ float intermediate = x + st->reg[0] * -q->a[0] + st->reg[1] * -q->a[1]; float out = intermediate * q->b[0] + st->reg[0] * q->b[1] + st->reg[1] * q->b[2]; st->reg[1] = st->reg[0]; st->reg[0] = intermediate; return out; } float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx) { float sum = 0.0f; for (ssize_t j=0; j>3]; /* Fetch sequence table item */ if (debug) DEBUG_PRINTN("|"); } int bv = table_byte & (0x80>>(i&7)); /* Extract bit */ bv = !!bv*2 - 1; /* Map 0, 1 -> -1, 1 */ if (debug) DEBUG_PRINTN("%s%d\033[0m", bv == 1 ? "\033[92m" : "\033[91m", (bv+1)/2); float acc_inner = 0.0f; for (size_t j=0; j