// PC test of the REAL fingerprint.c and detector.c. // gcc -I stubs -iquote ../../main host_test.c ../../main/fingerprint.c ../../main/detector.c -lm -o host_test #include #include #include "fingerprint.h" #include "detector.h" #include "test_vector.h" static int fails; #define CHECK(c, ...) do { if (!(c)) { printf("FAIL: " __VA_ARGS__); printf("\n"); fails++; } } while (0) int main(void) { CHECK(features_init() == ESP_OK, "features_init"); #if TEST_VECTOR_VALID static features_ctx_t ctx; float fp[NUM_BANDS], rms; bool ok = features_compute(&ctx, TEST_VECTOR_PCM, fp, &rms); float me = 0; for (int b = 0; b < NUM_BANDS; b++) { float e = fabsf(fp[b] - TEST_VECTOR_FP[b]); if (e > me) me = e; } printf("parity: ok=%d max|fp err|=%.2e rms C=%.4f py=%.4f\n", ok, me, rms, TEST_VECTOR_RMS); CHECK(ok && me < 1e-3f, "fingerprint parity"); #endif // degenerate inputs must not produce NaN static int16_t z[FRAME_LEN]; static features_ctx_t c2; float f2[NUM_BANDS], r2; CHECK(!features_compute(&c2, z, f2, &r2) && r2 == 0.0f, "silence -> invalid, rms 0"); for (int b = 0; b < NUM_BANDS; b++) CHECK(f2[b] == 0.0f, "silence fp zero"); // detector: 10-of-15 triggers once, cooldown 20 s, then re-arms detector_t d; detector_init(&d); detector_cfg_t cfg = { 15, 10, 20000 }; uint32_t t = 0; int trig = 0, first = -1; for (int i = 0; i < 40; i++, t += 32) if (detector_update(&d, i >= 5 && i < 30, t, &cfg)) { trig++; if (first < 0) first = i; } CHECK(trig == 1 && first == 14, "single trigger at 10th match (got %d trig, first %d)", trig, first); CHECK(d.state == DET_COOLDOWN, "cooldown after trigger"); for (int i = 0; i < 100; i++, t += 32) CHECK(!detector_update(&d, true, t, &cfg), "no trigger in cooldown"); t += 20000; detector_update(&d, false, t, &cfg); CHECK(d.state == DET_IDLE, "back to idle"); int n = 0; for (int i = 0; i < 12; i++, t += 32) n += detector_update(&d, true, t, &cfg); CHECK(n == 1, "re-arms and triggers again"); // sparse matches never trigger detector_reset(&d); n = 0; for (int i = 0; i < 300; i++, t += 32) n += detector_update(&d, i % 3 == 0, t, &cfg); CHECK(n == 0, "1-in-3 matches must not trigger 10/15"); printf(fails ? "HOST TEST FAILED\n" : "HOST TEST PASSED\n"); return fails != 0; }