Files
skills/docs/media/audio/audio-analysis-pitch/src/detector/pitch-detector.md
2026-05-29 08:20:56 +01:00

2.5 KiB

pitch-detector

Purpose

pitch-detector.ts exposes the PitchDetector class — the Analysis Op plugin (plugin slot 3 in the @suaveplan/audio-* family) that estimates the fundamental frequency of an AudioDocument. It supports whole-document analysis (analyze), streaming refinement (analyzeStream), and synchronous single-block analysis (analyzeBlock) for real-time visualisation.

Three estimators are selectable per call — YIN (default), McLeod, and cepstrum — letting callers pick the right trade-off for the material at hand without coupling to a different package.

Features

  • Three pitch algorithms behind the algorithm option.
  • Configurable frequency range via minFreq / maxFreq and frame size.
  • AbortSignal support across all three entry points.
  • Zod boundary validation on every options object.
  • OpenTelemetry spans per detector run, counter for total runs, histograms for run and block duration.
  • Stable error codes (INVALID_OPTIONS, ABORTED, UNSUPPORTED_FORMAT, INSUFFICIENT_DATA) all routable through AudioAnalysisError.

Usage: Basic

import { PitchDetector } from "@suaveplan/audio-analysis-pitch";

const detector = new PitchDetector();
const result = await detector.analyze(doc);
console.log(result.pitch, "Hz", "midi:", result.midiNote);

Usage: Advanced

import { PitchDetector } from "@suaveplan/audio-analysis-pitch";

const detector = new PitchDetector();
const controller = new AbortController();
const opts = { algorithm: "mcleod" as const, minFreq: 50, maxFreq: 1_000, signal: controller.signal };
const out: number[] = [];
for await (const r of detector.analyzeStream(doc, opts)) {
    out.push(r.pitch);
    if (out.length >= 100) controller.abort();
}

API Reference

  • class PitchDetector { name: "pitch-detector"; version: string; description: string; analyze(doc, opts?); analyzeStream(doc, opts?); analyzeBlock(block, ctx) }.
  • interface PitchDetectorOptions { algorithm?, minFreq?, maxFreq?, frameSize?, hopSize?, signal? }.
  • interface PitchResult extends AnalysisResult { op: "pitch-detector"; pitch; midiNote; confidence; timestamp; duration }.

Implementation Notes

analyze aggregates results by keeping the highest-confidence pitch across all frames. analyzeStream yields per-block estimates with a running max confidence so the stream is non-decreasing in expectation. Both honour an AbortSignal checked at every block boundary. analyzeBlock is allocation-light: it skips the Zod schema (the block path is hot) and uses the package defaults.