Files
buzz_detector/main/detector.c
T
2026-10-13 19:47:46 -05:00

52 lines
1.4 KiB
C

#include <string.h>
#include "detector.h"
void detector_init(detector_t *d) { memset(d, 0, sizeof(*d)); d->state = DET_IDLE; }
void detector_reset(detector_t *d) { d->state = DET_IDLE; d->hist = 0; }
bool detector_is_match(float rms, float score, float min_rms, float threshold)
{
return rms >= min_rms && score >= threshold;
}
bool detector_update(detector_t *d, bool match, uint32_t now_ms, const detector_cfg_t *cfg)
{
uint32_t n = cfg->win_n < 1 ? 1 : (cfg->win_n > 32 ? 32 : cfg->win_n);
uint32_t m = cfg->win_m < 1 ? 1 : (cfg->win_m > n ? n : cfg->win_m);
switch (d->state) {
case DET_IDLE: {
d->hist = (d->hist << 1) | (match ? 1u : 0u);
uint32_t mask = (n == 32) ? 0xFFFFFFFFu : ((1u << n) - 1u);
if ((uint32_t)__builtin_popcount(d->hist & mask) >= m) {
d->state = DET_TRIGGERED;
d->triggers++;
return true;
}
break;
}
case DET_TRIGGERED:
d->state = DET_COOLDOWN;
d->cooldown_start_ms = now_ms;
d->hist = 0;
break;
case DET_COOLDOWN:
if ((uint32_t)(now_ms - d->cooldown_start_ms) >= cfg->cooldown_ms) {
d->state = DET_IDLE;
d->hist = 0;
}
break;
}
return false;
}
const char *detector_state_name(det_state_t s)
{
switch (s) {
case DET_IDLE: return "IDLE";
case DET_TRIGGERED: return "TRIGGERED";
case DET_COOLDOWN: return "COOLDOWN";
}
return "?";
}