Skip to content
Guide

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 AudioContext from a user gesture to avoid autoplay blocks.
  • Tune minVolumeDecibels and minClarityPercent to 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 getUserMedia permissions and HTTPS are in place.
  • Set minClarityPercent between 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.
Built as a personal SvelteKit 5 lab with Supabase auth. Guides, patterns, and a playground you can actually ship.
Command Palette
Search for a command to run