Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::signal::YinTrackerT< SampleType > Class Template Reference

Monophonic fundamental-frequency estimator, after de Cheveigné & Kawahara 2002 [1], steps 1–5. More...

#include <yin_tracker.hpp>

Public Member Functions

void prepare (double sample_rate)
void reset ()
void discard_history () noexcept
 Constant-time logical reset for audio-thread fault recovery.
void set_f0_range (double min_hz, double max_hz)
 Sets the tracked range.
double f0_min_hz () const
double f0_max_hz () const
bool process (SampleType x)
 Feeds one sample.
double f0_hz () const
 The current estimate.
double tau_samples () const
 The refined period in samples, before the Hz conversion.
bool voiced () const
 False when the frame carried no stable period (min d' > kYinThreshold).
double min_cmnd () const
 The frame's minimum CMND — the tracker's own confidence reading.
int latency_samples () const
 Series law 5: the estimate for a frame needs the whole window, so this is W.
int window_samples () const
int integration_samples () const
int tau_min () const
int tau_max () const
double cost_mac_per_sample () const
 Amortized analysis cost, so a caller can see before profiling that this is a one-per-track block rather than a per-voice one.

Static Public Member Functions

static constexpr int hop_samples ()

Static Public Attributes

static constexpr double kF0MinDefault = 80.0
 Lowest tracked fundamental.
static constexpr double kF0MinLimit = 50.0
static constexpr double kF0MaxLimit = 2000.0
static constexpr double kF0MaxDefault = 1000.0
 Highest tracked fundamental.
static constexpr double kYinThreshold = 0.10
 The absolute threshold on the cumulative mean normalized difference.
static constexpr int kHop = 256
 Analysis hop — the control cadence.
static constexpr int kMedianTaps = 3
 Median taps for octave-flip rejection.
static constexpr int kMaxMedianTaps = 5

Detailed Description

template<typename SampleType = float>
class pulp::signal::YinTrackerT< SampleType >

Monophonic fundamental-frequency estimator, after de Cheveigné & Kawahara 2002 [1], steps 1–5.

RT contract: prepare(sample_rate) sizes the analysis buffers and is the only allocating call. process, set_*, and reset allocate nothing, take no locks, and never throw. The per-hop analysis is a burst of work on ONE sample in every kHop — see cost_mac_per_sample for what that costs and why you should not instantiate thirty of these.

Steps 1–5 are the paper's. Step 6 (best-local-estimate) is omitted and replaced by a 3-tap median across hops, which is an original heuristic and cheaper — it kills the single-frame octave flips that are YIN's dominant failure mode at the cost of one extra hop of settling. That substitution is a design choice and is NOT a claim to implement the paper's step 6.

Member Function Documentation

◆ cost_mac_per_sample()

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::cost_mac_per_sample ( ) const
inline

Amortized analysis cost, so a caller can see before profiling that this is a one-per-track block rather than a per-voice one.

◆ discard_history()

template<typename SampleType = float>
void pulp::signal::YinTrackerT< SampleType >::discard_history ( )
inlinenoexcept

Constant-time logical reset for audio-thread fault recovery.

◆ f0_hz()

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::f0_hz ( ) const
inline

The current estimate.

Held through unvoiced frames rather than dropping to zero, so a caller that ignores voiced() still gets a sane number.

◆ f0_max_hz()

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::f0_max_hz ( ) const
inline

◆ f0_min_hz()

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::f0_min_hz ( ) const
inline

◆ hop_samples()

template<typename SampleType = float>
constexpr int pulp::signal::YinTrackerT< SampleType >::hop_samples ( )
inlinestaticconstexpr

◆ integration_samples()

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::integration_samples ( ) const
inline

◆ latency_samples()

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::latency_samples ( ) const
inline

Series law 5: the estimate for a frame needs the whole window, so this is W.

There is no zero-latency variant of a period-length autocorrelation. Report it; do not hide it.

◆ min_cmnd()

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::min_cmnd ( ) const
inline

The frame's minimum CMND — the tracker's own confidence reading.

◆ prepare()

template<typename SampleType = float>
void pulp::signal::YinTrackerT< SampleType >::prepare ( double sample_rate)
inline

◆ process()

template<typename SampleType = float>
bool pulp::signal::YinTrackerT< SampleType >::process ( SampleType x)
inline

Feeds one sample.

Returns true on the samples where a NEW estimate landed, so a caller can re-run its control chain only on those.

◆ reset()

template<typename SampleType = float>
void pulp::signal::YinTrackerT< SampleType >::reset ( )
inline

◆ set_f0_range()

template<typename SampleType = float>
void pulp::signal::YinTrackerT< SampleType >::set_f0_range ( double min_hz,
double max_hz )
inline

Sets the tracked range.

Takes effect at the next prepare, because the window length — and therefore the reported latency and the buffer sizes — are derived from it. Changing latency mid-stream would be a worse surprise than requiring a re-prepare.

◆ tau_max()

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::tau_max ( ) const
inline

◆ tau_min()

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::tau_min ( ) const
inline

◆ tau_samples()

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::tau_samples ( ) const
inline

The refined period in samples, before the Hz conversion.

◆ voiced()

template<typename SampleType = float>
bool pulp::signal::YinTrackerT< SampleType >::voiced ( ) const
inline

False when the frame carried no stable period (min d' > kYinThreshold).

◆ window_samples()

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::window_samples ( ) const
inline

Member Data Documentation

◆ kF0MaxDefault

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::kF0MaxDefault = 1000.0
staticconstexpr

Highest tracked fundamental.

Covers soprano and the guitar's upper register. [design parameter] default 1000 Hz, range 500 .. 2000 Hz.

◆ kF0MaxLimit

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::kF0MaxLimit = 2000.0
staticconstexpr

◆ kF0MinDefault

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::kF0MinDefault = 80.0
staticconstexpr

Lowest tracked fundamental.

Covers a bass/guitar low E (~82 Hz) and a low male voice. Sets the analysis window, and therefore the latency. [design parameter] default 80 Hz, range 50 .. 200 Hz.

◆ kF0MinLimit

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::kF0MinLimit = 50.0
staticconstexpr

◆ kHop

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::kHop = 256
staticconstexpr

Analysis hop — the control cadence.

256 samples at 48 kHz is ~187 estimates/s. [design parameter] default 256, range 128 .. 512.

◆ kMaxMedianTaps

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::kMaxMedianTaps = 5
staticconstexpr

◆ kMedianTaps

template<typename SampleType = float>
int pulp::signal::YinTrackerT< SampleType >::kMedianTaps = 3
staticconstexpr

Median taps for octave-flip rejection.

[design parameter] default 3, range {1 (off), 3, 5}.

◆ kYinThreshold

template<typename SampleType = float>
double pulp::signal::YinTrackerT< SampleType >::kYinThreshold = 0.10
staticconstexpr

The absolute threshold on the cumulative mean normalized difference.

Published: [1] §III.D uses 0.10. Range 0.05 .. 0.20 is the paper's own sensitivity discussion, not a free knob.


The documentation for this class was generated from the following file:
  • /home/runner/work/pulp/pulp/core/signal/include/pulp/signal/yin_tracker.hpp