37 lines
1.3 KiB
C
37 lines
1.3 KiB
C
#pragma once
|
|
// Pure state machine: no ESP-IDF dependencies, can be compiled and tested on a PC.
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
typedef enum { DET_IDLE = 0, DET_TRIGGERED, DET_COOLDOWN } det_state_t;
|
|
|
|
typedef struct {
|
|
uint32_t win_n; // window length in frames (clamped to 1..32)
|
|
uint32_t win_m; // matches required (clamped to 1..win_n)
|
|
uint32_t cooldown_ms;
|
|
} detector_cfg_t;
|
|
|
|
typedef struct {
|
|
det_state_t state;
|
|
uint32_t hist; // bit 0 = newest frame, 1 = matched
|
|
uint32_t frame_index;
|
|
uint32_t match_time_ms[32];
|
|
uint32_t buzz_start_ms;
|
|
uint32_t last_match_ms;
|
|
uint32_t last_completed_start_ms;
|
|
uint32_t triggers;
|
|
} detector_t;
|
|
|
|
void detector_init(detector_t *d);
|
|
void detector_reset(detector_t *d); // back to IDLE with empty history
|
|
|
|
// Loudness gate AND score >= threshold.
|
|
bool detector_is_match(float rms, float score, float min_rms, float threshold);
|
|
|
|
// Feed one frame. Returns true when a buzz event ends and writes its duration.
|
|
// Matches within cooldown_ms extend the same event; the final quiet tail is
|
|
// excluded from its duration.
|
|
bool detector_update(detector_t *d, bool match, uint32_t now_ms, const detector_cfg_t *cfg,
|
|
uint32_t *buzz_duration_ms);
|
|
const char *detector_state_name(det_state_t s);
|