Pitch Detection
Public facade for pitch detection — realtime and batch (ADR-001).
What is Pitch Detection?
Pitch detection estimates the fundamental frequency (F0) of a monophonic audio signal. VoxaTrace offers two algorithms:
YIN — classic DSP autocorrelation, no ML dependency, frame-by-frame.
SwiftF0 — lightweight neural network (95k params), batch-oriented, higher accuracy for vocals at the cost of requiring an ONNX model bundle.
This facade provides factory methods for two workflows:
Realtime detection via PitchDetector — feed audio buffers one at a time, get a PitchPoint per frame. Accumulates a live pitch contour.
Batch extraction via PitchContourExtractor — pass a complete audio recording, get back a full PitchContour with optional post-processing.
When to Use
| Scenario | Use | Why |
|---|---|---|
| Live singing feedback (karaoke, practice) | createDetector | Frame-by-frame with live contour |
| Offline melody scoring / intonation analysis | createContourExtractor | Full contour with cleanup |
| Post-process an existing contour | PitchProcessing.process() | Not detection — uses this facade's output |
| Histogram / transcription on a contour | PitchAnalysis.* | Also not detection — downstream |
Quick Start
Kotlin
// Realtime detection
val detector = PitchDetection.createDetector()
val point = detector.detect(audioBuffer, sampleRate = 16000)
detector.close()
// Batch extraction
val extractor = PitchDetection.createContourExtractor(
ContourExtractorConfig.SCORING,
modelProvider = { ModelLoader.loadSwiftF0() }
)
val contour = extractor.extract(audioSamples, sampleRate = 16000)
extractor.release()Swift
// Realtime detection (accepts native [Float], any sample rate — ADR-017)
let detector = PitchDetection.createDetector()
let point = detector.detect(samples: audioBuffer, sampleRate: 48000)
detector.close()
// Batch extraction
let extractor = PitchDetection.createContourExtractor(config: .scoring) {
ModelLoader.shared.loadSwiftF0()
}
let contour = extractor.extract(audio: audioSamples, sampleRate: 48000)
extractor.release()Common Pitfalls
SwiftF0 requires a model: Pass
modelProviderexplicitly or register viaAIModelRegistry.registerSwiftF0 { ... }at startup. Forgetting this throws at create-time.Release when done: Both PitchDetector and PitchContourExtractor hold native resources. Call
close()/release()to avoid leaks.Mono input only: Both algorithms expect single-channel audio.
SonixDecoder.decode()auto-converts stereo to mono (ADR-017).PRECISE is not for realtime: PitchDetectorConfig.PRECISE uses a 4096-sample buffer — too expensive per frame for real-time use (ADR-020).
See also
The realtime detector interface returned by createDetector
The batch extractor returned by createContourExtractor
For post-processing a contour (smoothing, octave correction)
For histogram, quantization, and transcription on a contour
Configuration for detection (presets, builder, .copy)
Configuration for extraction
Functions
Create a pitch contour extractor for batch (offline) processing.
Create a realtime pitch detector.