Pitchy pitch detection best practices
Pitchy is lightweight and fast, but the quality you get depends on the audio you feed it and how you filter the results. Use these practices to keep detection stable across microphones.
Best practices
- Start the
AudioContextfrom a user gesture to avoid autoplay blocks. - Tune
minVolumeDecibelsandminClarityPercentto filter noise before plotting. - Keep pitch ranges narrow (voice vs. instrument) to reduce false positives.
- Pick a buffer size that balances latency (smaller) and stability (larger).
- Sample every 40-60ms for smoother curves without hammering the main thread.
- Stop tracks and close the audio context on navigation or teardown.
SvelteKit-friendly setup
<script lang="ts">
import { onDestroy } from "svelte";
import { PitchDetector } from "pitchy";
let analyser;
let detector;
let inputBuffer;
let audioContext;
async function start(stream) {
audioContext = new AudioContext();
analyser = new AnalyserNode(audioContext, { fftSize: 2048 });
audioContext.createMediaStreamSource(stream).connect(analyser);
detector = PitchDetector.forFloat32Array(analyser.fftSize);
detector.minVolumeDecibels = -10;
inputBuffer = new Float32Array(detector.inputLength);
}
function sample() {
analyser.getFloatTimeDomainData(inputBuffer);
const [pitch, clarity] = detector.findPitch(inputBuffer, audioContext.sampleRate);
}
onDestroy(() => {
audioContext?.close();
});
</script> Tuning checklist
- Verify
getUserMediapermissions and HTTPS are in place. - Set
minClarityPercentbetween 90-98 for noisy rooms. - Use a log scale for pitch graphs to avoid visual jitter.
- Consider averaging 3-5 samples before display if the line chatters.
- Reset the audio context after changing sample rate or buffer size.