|
DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
|
Thread-safe YIN pitch detector with lock-free readout. More...
#include <PitchDetector.h>
Public Member Functions | |
| void | prepare (double sampleRate, int windowSize=0, int hopSize=0) |
| Prepares the detector and allocates internal structures. | |
| void | pushSamples (std::span< const T > samples) noexcept |
| Pushes audio samples into the analysis buffer. | |
| T | getFrequencyHz () const noexcept |
| Returns the detected frequency in Hz safely from any thread. | |
| T | getConfidence () const noexcept |
| Returns the detection confidence [0.0 - 1.0] safely from any thread. | |
| int | getMidiNote () const noexcept |
| Returns nearest MIDI note (69 = A4), or -1 if unvoiced. | |
| T | getCentsOffset () const noexcept |
| Returns cent offset from the nearest MIDI note [-50, +50]. | |
| void | setThreshold (T threshold) noexcept |
| Sets the sensitivity threshold (clamped to 0.01 - 0.5). Lower is stricter. Non-finite values are ignored. | |
| T | getThreshold () const noexcept |
| Returns the sensitivity threshold. | |
| int | getWindowSize () const noexcept |
| int | getHopSize () const noexcept |
| void | reset () noexcept |
| Resets state buffers. Not thread-safe with pushSamples(). | |
Thread-safe YIN pitch detector with lock-free readout.
A non-finite stretch in the input signal simply reads as "unvoiced" (frequency 0, confidence 0) and flushes out of the analysis window on its own: the pipeline holds no recursive state, so the detector self-recovers once clean samples refill the window.
| T | Sample type (float or double). |
Definition at line 54 of file PitchDetector.h.
|
inlinenoexcept |
Returns cent offset from the nearest MIDI note [-50, +50].
Definition at line 232 of file PitchDetector.h.
|
inlinenoexcept |
Returns the detection confidence [0.0 - 1.0] safely from any thread.
Definition at line 218 of file PitchDetector.h.
|
inlinenoexcept |
Returns the detected frequency in Hz safely from any thread.
Definition at line 212 of file PitchDetector.h.
|
inlinenoexcept |
Definition at line 267 of file PitchDetector.h.
|
inlinenoexcept |
Returns nearest MIDI note (69 = A4), or -1 if unvoiced.
Definition at line 224 of file PitchDetector.h.
|
inlinenoexcept |
Returns the sensitivity threshold.
Definition at line 251 of file PitchDetector.h.
|
inlinenoexcept |
Definition at line 263 of file PitchDetector.h.
|
inline |
Prepares the detector and allocates internal structures.
Must be called before audio processing begins. Zero allocations happen after this point. Release-safe: a non-finite or non-positive sample rate is ignored (no-op keeping the previous configuration); an explicit windowSize is clamped to [64, 1 << 20].
| sampleRate | The system sample rate in Hz. |
| windowSize | Analysis window in samples. Values <= 0 (the default) select the AUTOMATIC window: the smallest power of two in [512, 16384] spanning at least 2048/48000 s (~42.7 ms) at sampleRate – 2048 at 44.1/48 kHz, 4096 at 88.2/96 kHz, 8192 at 176.4/192 kHz, 16384 at 384 kHz, 512 at 8 kHz. Read it back with getWindowSize(). |
| hopSize | Samples between detections. Values <= 0 (the default) select windowSize/4, which is 512 at the 44.1/48 kHz window and keeps the detection RATE at ~one per 10.7 ms at every sample rate. Explicit positive values are clamped to [1, windowSize]. |
THE WINDOW IS A REGISTER, NOT A COUNT. YIN searches lags tau in [2, windowSize/2), so the lowest fundamental the detector can reach is
fmin = fs / (windowSize/2 - 1) (approximately 2*fs/windowSize)
– a property of the RATIO fs/windowSize alone. Measured, identical across rates at equal ratio: fs/windowSize = 23.44 Hz recovers down to A1 55 Hz (48 kHz/2048, 96 kHz/4096, 192 kHz/8192 all agree to within 0.01 cents); fs/windowSize = 5.86 Hz reaches C1 32.7 Hz. Holding the COUNT fixed instead moves the floor with the rate: an explicit 2048 window gives fmin 46.9 Hz at 48 kHz but 93.8 Hz at 96 kHz and 187.7 Hz at 192 kHz, so E1/A1/E2 – and at 176.4/192 kHz A2 as well – are simply never reported. Out-of-register notes read as unvoiced (0 Hz, confidence 0) rather than as a wrong pitch: measured across 44.1..192 kHz on band-limited sawtooths from E1 to A5, every reading was either correct to within 0.1 cents or absent, never confidently wrong. The automatic window keeps fmin at 43.1 Hz (44.1 kHz family) / 46.9 Hz (48 kHz family) from 8 kHz all the way to 384 kHz, where it reaches the 16384 clamp. ABOVE 384 kHz the ceiling binds and the floor climbs again (measured 93.8 Hz at 768 kHz) – documented, not fixed; pass an explicit window there. For a lower floor at any rate pass an explicit window: fmin scales as fs/windowSize, so doubling the window halves it.
Definition at line 102 of file PitchDetector.h.
|
inlinenoexcept |
Pushes audio samples into the analysis buffer.
Automatically triggers pitch detection when the hop size is reached. Lock-free and allocation-free. No-op before prepare().
| samples | Span of input audio data (mono). |
Definition at line 185 of file PitchDetector.h.
|
inlinenoexcept |
Resets state buffers. Not thread-safe with pushSamples().
Definition at line 270 of file PitchDetector.h.
|
inlinenoexcept |
Sets the sensitivity threshold (clamped to 0.01 - 0.5). Lower is stricter. Non-finite values are ignored.
Definition at line 244 of file PitchDetector.h.