Skip to content

Commit

Permalink
EnvPitchDetector: rough draft of envelope based on lowpass(signal^2).
Browse files Browse the repository at this point in the history
  • Loading branch information
cosinekitty committed Jan 30, 2025
1 parent 1b1cc4b commit b7bf50d
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions src/env_pitch_detect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,21 @@ namespace Sapphire
filter_t loCutFilter[maxChannels];
filter_t hiCutFilter[maxChannels];
filter_t jitterFilter[maxChannels];
filter_t amplFilter[maxChannels];
float loCutFrequency = 20;
float hiCutFrequency = 3000;
float jitterCornerFrequency = 10;
float amplCornerFrequency = 10;
int recoveryCountdown; // how many samples remain before trying to filter again (CPU usage limiter)

value_t updateAmplitude(int channel, value_t signal)
{
// Square the signal and filter the result.
// This gives us a time-smeared measure of power.
amplFilter[channel].SetCutoffFrequency(amplCornerFrequency);
return amplFilter[channel].UpdateLoPass(signal*signal, currentSampleRate);
}

void updateWaveLength(int channel, int wavelengthSamples)
{
// The wavelengths we receive here will often be quite jittery.
Expand Down Expand Up @@ -56,10 +66,12 @@ namespace Sapphire
ascendSamples[c] = 0;
descendSamples[c] = 0;
filteredWaveLength[c] = 0;

// Reset all filters in case they went non-finite.
loCutFilter[c].Reset();
hiCutFilter[c].Reset();
jitterFilter[c].Reset();
amplFilter[c].Reset();
}
}

Expand Down Expand Up @@ -107,12 +119,12 @@ namespace Sapphire

// Reject frequencies lower than we want to keep.
loCutFilter[c].SetCutoffFrequency(loCutFrequency);
float locut = loCutFilter[c].UpdateHiPass(inFrame[c], sampleRateHz);
value_t locut = loCutFilter[c].UpdateHiPass(inFrame[c], sampleRateHz);

// Reject frequencies higher than we want to keep.
// The band-pass result is our signal to feed through envelope and pitch detection.
hiCutFilter[c].SetCutoffFrequency(hiCutFrequency);
float signal = hiCutFilter[c].UpdateLoPass(locut, sampleRateHz);
value_t signal = hiCutFilter[c].UpdateLoPass(locut, sampleRateHz);

// Make sure we have a normal numeric value for our signal.
if (!std::isfinite(signal))
Expand All @@ -127,6 +139,8 @@ namespace Sapphire
return;
}

outEnvelope[c] = updateAmplitude(c, signal);

// Keep waiting until we go from negative to positive, or positive to negative,
// with any number (zero or more) of 0-valued samples in between them.
if (signal != 0)
Expand Down Expand Up @@ -155,8 +169,8 @@ namespace Sapphire
// samplerate/wavelength: [samples/sec]/[samples] = [1/sec] = [Hz]
if (filteredWaveLength[c] > sampleRateHz/4000)
{
float frequencyHz = sampleRateHz / filteredWaveLength[c];
outPitchVoct[c] = log2(frequencyHz / centerFrequencyHz);
value_t frequencyHz = sampleRateHz / filteredWaveLength[c];
outPitchVoct[c] = std::log2(frequencyHz / centerFrequencyHz);
}
}
}
Expand Down

0 comments on commit b7bf50d

Please sign in to comment.