first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
# yin
## Purpose
`yin.ts` ships three fundamental-frequency estimators behind a unified `PitchEstimate` shape so the `PitchDetector` can swap algorithms via the `algorithm` option without callers branching on the result type. The default is YIN (de Cheveigné & Kawahara, 2002), with McLeod Pitch Method (MPM) and a real-cepstrum estimator available for material where they outperform YIN.
This file also vendors a small radix-2 real FFT plus `nextPow2` / `realFftMagnitude` helpers consumed by the chromagram and cepstrum paths so the package has no hard dependency on `@suaveplan/audio-analysis-spectrum`.
## Features
- `yinPitch` — difference function, cumulative mean normalised difference, absolute threshold pick at 0.1, parabolic interpolation.
- `mcleodPitch` — NSDF + key-maxima picking with threshold-relative-to-global-max.
- `cepstrumPitch` — log-magnitude inverse FFT with quefrency peak in the lag window.
- Robust no-pitch result: returns `pitch: 0`, `confidence: 0` when the input is silent or has no detectable periodicity.
- Vendored radix-2 FFT for self-contained operation.
## Usage: Basic
```ts
import { yinPitch } from "@suaveplan/audio-analysis-pitch/algorithms/yin";
const frame = new Float32Array(4096);
for (let i = 0; i < frame.length; i++) {
frame[i] = Math.sin((2 * Math.PI * 440 * i) / 48_000);
}
const { pitch, confidence } = yinPitch(frame, 48_000, 20, 20_000);
```
## Usage: Advanced
```ts
import {
cepstrumPitch,
mcleodPitch,
yinPitch,
} from "@suaveplan/audio-analysis-pitch/algorithms/yin";
function multiAlgorithmEnsemble(frame: Float32Array, sr: number) {
const yin = yinPitch(frame, sr, 50, 2_000);
const mpm = mcleodPitch(frame, sr, 50, 2_000);
const cep = cepstrumPitch(frame, sr, 50, 2_000);
return [yin, mpm, cep].sort((a, b) => b.confidence - a.confidence)[0];
}
```
## API Reference
- `interface PitchEstimate { pitch: number; confidence: number }`.
- `yinPitch(frame, sampleRate, minFreq, maxFreq): PitchEstimate`.
- `mcleodPitch(frame, sampleRate, minFreq, maxFreq, threshold = 0.85): PitchEstimate`.
- `cepstrumPitch(frame, sampleRate, minFreq, maxFreq): PitchEstimate`.
- `nextPow2(n: number): number`.
- `realFftMagnitude(frame: Float32Array): Float32Array`.
## Implementation Notes
YIN's CMNDF gives lag-zero a value of 1, suppressing the trivial autocorrelation peak. MPM walks the NSDF from the first negative crossing onward to avoid the same trivial peak. Parabolic interpolation around the chosen lag yields sub-sample precision. The cepstrum path is sample-rate-bound in resolution (one bin equals `sr/period²`), so its accuracy is coarser than YIN/MPM — typically within ±20 Hz at 48 kHz for a 4096-sample frame.