ESPectre SDK 2.8.0-280-gac7af68
Wi-Fi CSI motion sensing for ESP32 firmware
Loading...
Searching...
No Matches
filters.h
Go to the documentation of this file.
1/*
2 * ESPectre - Signal Filters
3 *
4 * Low-pass and Hampel filters used by the shared signal-processing
5 * pipeline.
6 *
7 * Author: Francesco Pace <francesco.pace@gmail.com>
8 * SPDX-License-Identifier: GPL-3.0-only
9 * Commercial licensing available under separate agreement; see LICENSING.md.
10 */
11#pragma once
12
13#include <cstdint>
14#include <cstddef>
15
16#include "filter_config.h"
17
18namespace espectre {
19
20// =============================================================================
21// Low-pass Filter (1st order Butterworth IIR)
22// =============================================================================
24 float b0; // Numerator coefficient
25 float a1; // Denominator coefficient (negated)
26 float x_prev; // Previous input
27 float y_prev; // Previous output
28 float cutoff_hz; // Cutoff frequency
29 bool enabled; // Whether filter is enabled
30 bool initialized; // Whether filter has been initialized with first sample
31};
32
33void lowpass_filter_init(lowpass_filter_state_t *state, float cutoff_hz,
34 float sample_rate_hz, bool enabled);
37
38// =============================================================================
39// Hampel Filter (MAD-based outlier removal)
40// =============================================================================
41constexpr float MAD_SCALE_FACTOR = 1.4826f; // Median Absolute Deviation scale factor
43 float buffer[HAMPEL_TURBULENCE_WINDOW_MAX]; // Circular buffer for values
44 uint8_t window_size; // Actual window size (3-11)
45 uint8_t index;
46 uint8_t count;
47 float threshold; // Configurable threshold (MAD multiplier)
48 bool enabled; // Whether filter is enabled
49};
50
51// Alias for cleaner naming
53
54void hampel_turbulence_init(hampel_turbulence_state_t *state, uint8_t window_size,
55 float threshold, bool enabled);
56
57/**
58 * Stateless Hampel decision over a caller-owned window.
59 *
60 * Shared numeric core: hampel_filter_turbulence() pushes into its ring and then
61 * defers here, so the outlier rule exists in exactly one place. The scratch is
62 * two stack arrays bounded by HAMPEL_TURBULENCE_WINDOW_MAX (11 floats each),
63 * which is small enough for the CSI callback stack.
64 *
65 * @return median when current_value is an outlier, otherwise current_value
66 */
67float hampel_filter(const float *window, size_t window_size,
68 float current_value, float threshold);
70
71} // namespace espectre
float hampel_filter(const float *window, size_t window_size, float current_value, float threshold)
Stateless Hampel decision over a caller-owned window.
constexpr uint8_t HAMPEL_TURBULENCE_WINDOW_MAX
void lowpass_filter_init(lowpass_filter_state_t *state, float cutoff_hz, float sample_rate_hz, bool enabled)
float hampel_filter_turbulence(hampel_turbulence_state_t *state, float turbulence)
constexpr float MAD_SCALE_FACTOR
Definition filters.h:41
float lowpass_filter_apply(lowpass_filter_state_t *state, float value)
hampel_turbulence_state_t hampel_filter_state_t
Definition filters.h:52
void hampel_turbulence_init(hampel_turbulence_state_t *state, uint8_t window_size, float threshold, bool enabled)
void lowpass_filter_reset(lowpass_filter_state_t *state)
float buffer[HAMPEL_TURBULENCE_WINDOW_MAX]
Definition filters.h:43