# key-finding ## Purpose `key-finding.ts` correlates an aggregated chromagram against 24 major/minor key profiles to estimate the musical key of a passage. Two profile sets ship: the classic Krumhansl-Schmuckler perceptual weights and Temperley's revised weights which reduce relative-major/minor confusion. The estimator returns the best-scoring key together with a `confidence` derived from the margin between the top and runner-up correlation, giving callers a usable proxy for how decisive the result was. ## Features - 12 tonics × 2 modes = 24 candidate keys scored per call. - Two interchangeable profile sets via the `profileSet` argument. - Pearson correlation as the scoring function — robust to multiplicative gain. - Stable pitch-class naming via `KEY_PROFILE_NAMES`. - Numerically safe: zero-denom Pearson collapses to zero rather than NaN. ## Usage: Basic ```ts import { detectKey } from "@suaveplan/audio-analysis-pitch/algorithms/key-finding"; const chroma = new Float32Array([6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88]); const { key, confidence } = detectKey(chroma); console.log(key); // "C major" ``` ## Usage: Advanced ```ts import { detectKey, type KeyProfileSet } from "@suaveplan/audio-analysis-pitch/algorithms/key-finding"; function compareProfiles(chroma: Float32Array) { const sets: KeyProfileSet[] = ["krumhansl-schmuckler", "temperley"]; return sets.map((set) => ({ set, ...detectKey(chroma, set) })); } ``` ## API Reference - `type KeyProfileSet = "krumhansl-schmuckler" | "temperley"`. - `interface KeyEstimate { key: string; mode: "major" | "minor"; tonic: number; confidence: number }`. - `detectKey(chroma: Float32Array, profileSet?: KeyProfileSet): KeyEstimate`. - `KEY_PROFILE_NAMES: readonly string[]` — `["C", "C#", "D", …]`. ## Implementation Notes Profiles are rotated to each tonic with O(1) lookup; for 24 candidates this is 24 Pearson computations per call, each O(12). The confidence is the normalised margin `(best - second) / max(|best|, ε)` clamped to `[0, 1]`. If the chromagram has zero variance the Pearson denominator collapses to zero and the function returns C major with zero confidence rather than NaN.