Spaces:
Sleeping
Sleeping
| // Pure fact primitives β no model, no state. (her-pattern: code owns the facts.) | |
| // MediaPipe Hands 21-landmark indices we care about. | |
| export const H = { | |
| WRIST: 0, | |
| THUMB_TIP: 4, | |
| INDEX_MCP: 5, INDEX_TIP: 8, | |
| MIDDLE_MCP: 9, MIDDLE_TIP: 12, | |
| RING_MCP: 13, RING_TIP: 16, | |
| PINKY_MCP: 17, PINKY_TIP: 20, | |
| }; | |
| export const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y); | |
| export const mid = (a, b) => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }); | |
| // Exponential moving average β kills landmark jitter before it hits the audio. | |
| export const ema = (prev, next, a = 0.5) => (prev == null ? next : prev * (1 - a) + next * a); | |
| export const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v)); | |
| // Linear normalize v in [lo,hi] -> [0,1], clamped. | |
| export const norm = (v, lo, hi) => clamp((v - lo) / (hi - lo), 0, 1); | |
| export const lerp = (a, b, t) => a + (b - a) * t; | |
| // Exponential map t in [0,1] -> [lo,hi] (for perceptually-correct cutoff/freq). | |
| export const expmap = (t, lo, hi) => lo * Math.pow(hi / lo, clamp(t, 0, 1)); | |