npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@audio/pitch

v2.0.3

Published

Pitch detection — umbrella for @audio/pitch-* atoms (YIN, pYIN, McLeod, HPS, cepstrum, SWIPE, autocorrelation, AMDF)

Readme

@audio/pitch test npm MIT

Pitch detection (F0 estimation). YIN, McLeod, pYIN, autocorrelation, AMDF, HPS, cepstrum, SWIPE.

Time-domain

YIN — cumulative mean normalized difference McLeod — normalized square difference (MPM) pYIN — probabilistic YIN with Beta prior Autocorrelation — normalized autocorrelation AMDF — average magnitude difference

Spectral

HPS — harmonic product spectrum Cepstrum — real cepstrum peak picking SWIPE — sawtooth waveform inspired estimator

Chroma, chord and key detection moved to @audio/mir (mir-chroma, mir-chord, mir-key).

Install

npm install @audio/pitch

Usage

import { yin, mcleod } from '@audio/pitch'

let fs = 44100
let frame = new Float32Array(2048)  // fill from your audio source

let result = yin(frame, { fs })
// → { freq: 440.1, clarity: 0.97 }  or  null

Works in Node.js and browser. No Web Audio API needed — operates on raw Float32Array samples.

Sliding windows — call repeatedly as new samples arrive:

let hop = 512
for (let i = 0; i + 2048 <= samples.length; i += hop) {
  let frame = samples.subarray(i, i + 2048)
  let result = yin(frame, { fs })
  if (result) console.log(i / fs, result.freq.toFixed(1))
}

Harmony pipeline — chroma → chord → key lives in @audio/mir:

import { chroma, chord, smoothChords, key } from '@audio/mir'

let frames = []
for (let i = 0; i + 4096 <= samples.length; i += 2048) {
  frames.push(chroma(samples.subarray(i, i + 4096), { fs, method: 'nnls' }))
}
let chords = smoothChords(frames, { selfProb: 0.5 })
let k = key(frames)

API

All pitch algorithms return { freq, clarity } | null:

  • freq — fundamental frequency in Hz
  • clarity — algorithm-specific confidence in [0, 1]
  • null — no periodic structure found (silence, noise, polyphony)

Time-domain algorithms (YIN, McLeod, pYIN, autocorrelation, AMDF) accept any buffer length. Spectral algorithms (HPS, cepstrum, SWIPE) require power-of-2 length.

Each algorithm is also installable standalone: npm install @audio/pitch-yin etc.


YIN

de Cheveigné & Kawahara, 2002. The reference algorithm for monophonic pitch estimation. Most cited, most tested, most robust.

import yin from '@audio/pitch-yin'

let result = yin(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | threshold | 0.15 | CMND threshold — lower = stricter, fewer detections |

Use when: General-purpose monophonic pitch tracking — speech, singing, solo instruments. The most reliable choice when in doubt. Not for: Polyphonic audio (returns dominant or null), real-time with hard latency budgets (needs full window). Ref: de Cheveigné & Kawahara, "YIN, a fundamental frequency estimator for speech and music", JASA 2002. Complexity: $O(N^2/4)$ — two nested passes over half the window.

McLeod

McLeod & Wyvill, 2005. Normalized square difference with smarter peak picking. Handles smaller windows — good for vibrato and fast pitch changes.

import mcleod from '@audio/pitch-mcleod'

let result = mcleod(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | threshold | 0.9 | Peak selection threshold as fraction of global max |

Use when: Vibrato tracking, small hop sizes, singing voice where YIN occasionally double-triggers. Not for: Highly noisy signals (NSDF is less thresholded than YIN's CMND). Ref: McLeod & Wyvill, "A smarter way to find pitch", ICMC 2005. Complexity: $O(N^2/4)$ — same asymptotic cost as YIN.

pYIN

Mauch & Dixon, 2014. Probabilistic YIN — runs YIN at multiple thresholds weighted by a Beta(2, 18) prior, producing a distribution over candidate pitches instead of a single hard pick. More robust than YIN on ambiguous frames.

import pyin from '@audio/pitch-pyin'

let result = pyin(samples, { fs: 44100 })
// → { freq: 440.1, clarity: 0.92, candidates: [{ freq: 440.1, prob: 0.85 }, ...] }

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | minFreq | 50 | Minimum detectable frequency (Hz) | | maxFreq | 2000 | Maximum detectable frequency (Hz) |

Use when: Ambiguous pitched content — breathy vocals, noisy recordings, or when you need a pitch posterior for downstream HMM tracking. Not for: Clean signals where YIN already works well (pYIN is ~10× slower due to multi-threshold sweep). Ref: Mauch & Dixon, "pYIN: A Fundamental Frequency Estimator Using Probabilistic Threshold Distributions", ICASSP 2014.

Autocorrelation

Normalized autocorrelation — the simplest pitch estimator. Educational baseline.

import autocorrelation from '@audio/pitch-autocorrelation'

let result = autocorrelation(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | threshold | 0.5 | Minimum normalized autocorrelation value to accept |

Use when: Learning, quick prototypes, signals with strong dominant periodicity and low noise. Not for: Production — octave errors are common without additional heuristics. Ref: Rabiner, "Use of autocorrelation analysis for pitch detection", IEEE TASSP 1977. Complexity: $O(N^2/4)$.

AMDF

Ross et al., 1974. Average Magnitude Difference Function — the classical predecessor to YIN. Measures average absolute difference between a signal and its delayed copy; minima indicate periodicity.

import amdf from '@audio/pitch-amdf'

let result = amdf(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | minFreq | 50 | Minimum detectable frequency (Hz) | | maxFreq | 2000 | Maximum detectable frequency (Hz) | | threshold | 0.3 | Normalized AMDF dip threshold |

Use when: Low-complexity environments, embedded systems. Simpler and cheaper than YIN (no squaring, no cumulative normalization). Not for: Noisy signals — lacks YIN's cumulative normalization that suppresses octave errors. Ref: Ross et al., "Average magnitude difference function pitch extractor", IEEE TASSP 1974. Complexity: $O(N^2/4)$.


HPS

Schroeder, 1968. Harmonic Product Spectrum — multiplies the spectrum by its downsampled copies so that harmonic peaks align at the fundamental. Robust to the missing-fundamental problem.

import hps from '@audio/pitch-hps'

let result = hps(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | harmonics | 5 | Number of harmonic products | | minFreq | 50 | Minimum detectable frequency (Hz) | | maxFreq | 4000 | Maximum detectable frequency (Hz) | | cents | 10 | Candidate spacing in cents | | threshold | 0.1 | Minimum clarity to accept |

Use when: Harmonic-rich signals (guitar, piano, brass). Naturally handles missing fundamentals. Not for: Pure sinusoids (only one harmonic), very noisy signals. Ref: Schroeder, "Period histogram and product spectrum", JASA 1968. Requires: Power-of-2 window length.

Cepstrum

Noll, 1967. Real cepstrum — $c(\tau) = \text{IFFT}(\log |\text{FFT}(x)|)$. A peak at quefrency $\tau$ corresponds to period $\tau$ in the time domain.

import cepstrum from '@audio/pitch-cepstrum'

let result = cepstrum(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | minFreq | 50 | Minimum detectable frequency (Hz) | | maxFreq | 2000 | Maximum detectable frequency (Hz) | | threshold | 0.3 | Minimum clarity to accept |

Use when: Harmonic signals where you want a clean spectral-domain method. Good pedagogical complement to time-domain algorithms. Not for: Low-pitched signals (quefrency resolution is limited by window length). Ref: Noll, "Cepstrum pitch determination", JASA 1967. Requires: Power-of-2 window length.

SWIPE

Camacho & Harris, 2008. SWIPE' (Sawtooth Waveform Inspired Pitch Estimator, prime harmonics). Measures spectral similarity between the window and a sawtooth template whose lobes sit at prime harmonics. More accurate than HPS on clean instrumental signals; robust against octave errors because only prime harmonics contribute.

Simplified single-window form: uses one FFT instead of the multi-resolution loudness pyramid of the original paper — sufficient for stationary windows.

import swipe from '@audio/pitch-swipe'

let result = swipe(samples, { fs: 44100 })

| Param | Default | | |---|---|---| | fs | 44100 | Sample rate (Hz) | | minFreq | 60 | Minimum detectable frequency (Hz) | | maxFreq | 4000 | Maximum detectable frequency (Hz) | | cents | 10 | Candidate spacing in cents | | threshold | 0.15 | Minimum clarity to accept |

Use when: Clean instrumental signals, studio recordings, where sub-Hz accuracy matters. Not for: Very noisy or reverberant signals (single-window form lacks multi-resolution robustness of the full SWIPE'). Ref: Camacho & Harris, "A sawtooth waveform inspired pitch estimator for speech and music", JASA 2008. Requires: Power-of-2 window length.


Comparison

Pitch algorithms

| | YIN | McLeod | pYIN | AMDF | HPS | Cepstrum | SWIPE | |---|---|---|---|---|---|---|---| | Domain | time | time | time | time | spectral | spectral | spectral | | Accuracy | ★★★★★ | ★★★★ | ★★★★★ | ★★★ | ★★★★ | ★★★ | ★★★★★ | | Noise robustness | ★★★★★ | ★★★★ | ★★★★★ | ★★★ | ★★★ | ★★★ | ★★★★ | | Octave errors | rare | rare | rare | common | rare | occasional | rare | | Missing fundamental | no | no | no | no | yes | yes | yes | | Min window | ~4 periods | ~2 periods | ~4 periods | ~4 periods | power of 2 | power of 2 | power of 2 | | Best for | general | vibrato | ambiguous | embedded | harmonic-rich | pedagogical | studio |

See also

  • fourier-transform — FFT used by spectral algorithms
  • mir — chroma, chord, key, melody, structure, fingerprint
  • beat — onset detection, tempo estimation, beat tracking
  • digital-filter — filter design and processing
  • stretch — time stretching and pitch shifting
  • shift — pitch shifting algorithms