first commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user