Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ ctest --test-dir build --build-config Release --output-on-failure

In **Pitch Track** mode, the plugin detects the pitch of the incoming audio using the YIN algorithm, then ring-modulates the signal with an oscillator locked to that pitch (multiplied by the Rate Multiplier). The effect stays dry only until the tracker has a valid pitch, then follows the tracked carrier directly.

The tracker uses short analysis windows for normal guitar notes and runs longer analyses for low or uncertain pitches, with slower background audits for octave errors. It supports fundamentals down to 20 Hz without imposing the low-frequency analysis rate on the common path. Acquisition can take roughly 110 ms near 20 Hz because one cycle alone is 50 ms.

In **Manual** mode, the oscillator runs at a fixed frequency set by the Manual Rate knob.

## License
Expand Down
24 changes: 23 additions & 1 deletion source/dsp/PitchSmoother.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class PitchSmoother
hasValue = false;
smoothed = 0.0f;
cachedFreq = 0.0f;
lastDetectedFreq = 0.0f;
cachedLogFreq = 0.0f;
invalidSamples = 0;
releaseSamples = std::max(1, static_cast<int>(sr * 0.05f));
recomputeAlpha();
}

Expand All @@ -31,9 +35,23 @@ class PitchSmoother
inline float process(float detectedFreq, float confidence)
{
if (detectedFreq <= 0.0f || confidence < sensitivityThreshold)
{
if (hasValue && ++invalidSamples >= releaseSamples)
{
hasValue = false;
smoothed = 0.0f;
cachedFreq = 0.0f;
}
return cachedFreq;
}

float logFreq = std::log2(detectedFreq);
invalidSamples = 0;
if (detectedFreq != lastDetectedFreq)
{
lastDetectedFreq = detectedFreq;
cachedLogFreq = std::log2(detectedFreq);
}
float logFreq = cachedLogFreq;

if (!hasValue)
{
Expand Down Expand Up @@ -71,5 +89,9 @@ class PitchSmoother
float alpha = 0.5f;
float sensitivityThreshold = 0.5f;
float cachedFreq = 0.0f;
float lastDetectedFreq = 0.0f;
float cachedLogFreq = 0.0f;
int invalidSamples = 0;
int releaseSamples = 2205;
bool hasValue = false;
};
Loading
Loading