#pragma once #include #include /* Example: drift_x 1, offset_y 10, abs_threshold 0.1 */ typedef struct { uint32_t length; // data length (data & ref length must be equal) uint32_t drift_x; // allowed horizontal drift (Hz drift if values are 1 Hz FFT bins) float offset_y; // allowed vertical offset (bin amplitude, positive or negative) float abs_threshold; // absolute threshold (to fix preccision errors, also added to offset_y) } vec_match_cfg_t; /** * Match signal to reference, allowing for some offser and noise * * @param data matched data * @param ref reference data * @param cfg config struct * @param fuzzy_match_error error metric calculated with allowed drift and offset * @param abs_match_error error metric calculated from raw data (can be used if envelope match passes) * @return envelope match status (match using drift and offset) */ bool vec_match(const float *data, const float *ref, const vec_match_cfg_t *cfg, float *fuzzy_match_error, float *abs_match_error); /** * Match vectors of positive numbers. * Negative number indicates how many consecutive elements are zero (hence the compression). * * 1024-long vector [12, 0, ...] would be [12, -1023] * * Params otherwise the same as vec_match() */ bool vec_match_packed(const float *data, const float *ref, const vec_match_cfg_t *cfg, float *fuzzy_match_error, float *abs_match_error); /** * Compress a vector by replacing sequence of zeroes with a negative value indicating their count. * * Returned length may exceed result_capacity, but the buffer is never overrun. * That can be used to gradually increase the threshold until the compressed data fits in the result buffer. * * The compression is by definition lossy. * * @param result result vector (can be the same as data vector for in-place operation) * @param result_capacity size of result buffer. * @param data data vector * @param length data legth * @param threshold max value to be considered zero in the compression * @return length of result vector */ uint32_t vec_pack(float *result, uint32_t result_capacity, const float *data, uint32_t length, float threshold); /** * Unpack a vector compressed with vec_pack(). * * If returned length exceeds provided buffer capacity, it's an indication that you need to enlarge your buffer. * The buffer is never overrun, though. * * @param result result buffer * @param result_capacity result buffer size * @param compr_data compressed data vector * @param compr_length compressed data vector length * @return */ uint32_t vec_unpack(float *result, uint32_t result_capacity, const float *compr_data, uint32_t compr_length);