@maruaudio/dsp/analysis/voice-pitch-detector is a streaming YIN detector for sung and spoken voices. The input passes a second-order high-pass at 0.6 × the minimum pitch and a fourth-order Butterworth low-pass (two @maru/filters-biquad sections), then is decimated by floor(rate / 11025) (1 to 32), so the CMNDF search runs at a similar analysis rate whatever the host rate. The difference compares the newest frame with the frame τ samples earlier. The coarse lag then seeds a full-rate difference search, and a local-minimum walk plus a parabolic fit give the sub-sample period. Once voiced, the threshold relaxes to a hold threshold, and an octave guard replaces a half-period candidate with the double-lag dip when that dip also qualifies.
Parameters
configureVoicePitchDetector(state, minimumHz, maximumHz, threshold, minimumRms, hopSamples)
| Argument | Range as coded | Default from init | Unit |
|---|---|---|---|
minimumHz | 50 to 400 | 70 | Hz |
maximumHz | 2 × minimum to min(1600, analysis rate / 4) | 1100 | Hz |
threshold | 0.02 to 0.5; hold threshold is twice it, at most 0.5 | 0.15 | CMNDF |
minimumRms | 0 to 0.25 | 0.0005 | linear RMS |
hopSamples | 32 to 2048, rounded | round(rate × 0.0053333) (256 at 48 kHz) | samples |
Lifecycle
initVoicePitchDetector(sampleRate) (rate 8 to 384 kHz) sizes every ring and table from the rate and the 50 Hz floor, then configures the defaults → configureVoicePitchDetector at control rate → voicePitchDetectorTick(state, x) per sample, which returns 1 on the sample a fresh analysis completes → resetVoicePitchDetector, a full reset. Results: frequencyHz, midi, periodSamples, confidence, voiced, rms, candidateHz and delaySamples, the distance to the centre of the analysed span.
When to use it
Pitch correction and pitch-following carriers on a live voice, including low male voices at high sample rates (pitch and harmony). retune.test.ts feeds its pitch to @maru/modulation-retune.
Limits
- Mono sample tick; one analysis per hop. The frame is one period of the minimum pitch and never shorter than 12 ms.
- Realtime loops have constant bounds (448 analysis, 8192 full-rate samples). Rates below 22.05 kHz are not decimated.