feat(douanier): modular ears building blocks — /features + /analyze/samples (#38)
Two new CPU-native, torch-free, cached endpoints on the audio sub-API — the "interesting value points" for hexa beyond emotion, each the same shape/pattern as /analyze/emotion (upload → content-address → cache → compute). - POST /features → the ~35-dim audio feature stack (spectral moments, MFCCs, chroma/key, envelope/attack-decay, + rhythm/tempo). scope `features`. - POST /analyze/samples → per-sample EDA + role (percs|bass|melodic|tops|atmos) decided by the MEASURED spectrum (centroid + band energy), never the name; an optional ?name= only disambiguates breaks/drums (feedback_mastering_eda). scope `samples`. Engine: engines/feats.py is SELF-CONTAINED (vendored DSP), like ears_light — the deployed container holds only armada/api/, not armada/tide-table/, so it can NOT import sample_features/audio_lens at runtime. It mirrors their algorithms and fixes the librosa-0.11 tempo bug (feature.tempo, not the removed feature.rhythm.tempo that silently dropped tempo in the tide-table original). Wiring: a shared _cached() helper now backs all three analyze routes (DRY); healthz advertises the engines map; both routes are scope-gated via the gateway X-Scopes. Validated in the torch-free container: /features 200 (41 features, tempo 107.7, key=Amaj), /analyze/samples role-by-measurement, 403 scope gate, X-Douanier-Cache hit on repeat. 40/40 tests (added test_feats.py + endpoint cases).
Showing
armada/api/engines/feats.py
0 → 100644
This diff is collapsed.
Click to expand it.
armada/api/tests/test_feats.py
0 → 100644
Please
register
or
sign in
to comment