@maruaudio/dsp/analysis/pitch-detector is a streaming YIN pitch detector for monophonic input. Every 512 samples it compares a fixed 512-sample window against lags 40 to 640 over 1152 samples of history: squared difference, cumulative mean normalized difference (CMNDF), the first dip below the threshold walked down to its local minimum, then parabolic refinement of the period within ±1 sample, in the upstream f32 order. Confidence is 1 − CMNDF at the selected lag; an RMS gate marks quiet windows unvoiced.
Parameters
configurePitchDetector(state, minimumHz, maximumHz, threshold, minimumRms); non-finite values take the default.
| Argument | Range as coded | Default | Unit |
|---|---|---|---|
minimumHz | rate / 640 to rate / 40 | rate / 640 (75 Hz at 48 kHz) | Hz |
maximumHz | minimumHz to rate / 40 | rate / 40 (1200 Hz at 48 kHz) | Hz |
threshold | 0.01 to 0.5 | 0.15 | CMNDF |
minimumRms | 0 to 0.25 | 0.0001 | linear RMS |
Lifecycle
initPitchDetectorNode(sampleRate) preallocates the 2048-sample ring and the difference and CMNDF tables (rate clamped to 8 to 192 kHz) → configure → pitchDetectorNodeTick(state, x) per sample, returning frequencyHz / maximumHz while voiced and 0 otherwise → resetPitchDetectorNode, a full reset. preparePitchDetectorNodeSampleRate re-clamps the range at a new rate, keeping history. Results: frequencyHz, periodSamples, confidence, voiced, rms.
When to use it
Driving a PSOLA shifter or a pitch display from a steady monophonic source. For voices, @maru/analysis-voice-pitch-detector covers 50 to 1600 Hz at any rate (pitch and harmony).
Limits
- Mono; one analysis per 512-sample hop, the first after 1152 samples. Fixed in samples, the pitch range scales with the rate: at 96 kHz the floor is 150 Hz.
- Inputs are clamped to ±10⁶, non-finite inputs written as 0; each analysis is bounded at 512 × 640 difference operations.