better autotune speed

This commit is contained in:
michalcourson
2025-10-30 19:49:58 -04:00
parent d68a6d5c2a
commit 098bd49cb5
3 changed files with 59 additions and 16 deletions

View File

@ -6,6 +6,58 @@
#define PI_F 3.1415927410125732421875f #define PI_F 3.1415927410125732421875f
#endif #endif
class MidiPitchSmoother {
public:
MidiPitchSmoother() {
tau = .1;
dt = 2048.0f / 48000.0f;
PcorrPrev = 60.0f;
PtargPrev = 60;
}
void SetFrameTime(float frame_time) {
dt = frame_time;
}
void SetTimeConstant(float t) {
tau = t;
}
float update(float Pdet, int Ptarget) {
// Detect large jump (new note)
float diff = std::fabs(Pdet - PcorrPrev);
if (Ptarget != PtargPrev) {
// Immediately reset to new note
PcorrPrev = Pdet;
PtargPrev = Ptarget;
return PcorrPrev;
}
// Compute smoothing coefficient
float alpha = 1.0 - std::exp(-dt / tau);
// Smooth within same note
float PcorrNew = PcorrPrev + alpha * (Ptarget - PcorrPrev);
PcorrPrev = PcorrNew;
return PcorrNew;
}
private:
float tau; // Time constant (s)
float dt; // Frame time (s)
float PcorrPrev; // Previous corrected pitch (MIDI)
int PtargPrev; // Previous corrected pitch (MIDI)
};
MidiPitchSmoother out_midi_smoother;
void Shifter::SetAutoTuneSpeed(float val) {
out_midi_smoother.SetTimeConstant(val);
}
static inline float mtof(float m) static inline float mtof(float m)
{ {
return powf(2, (m - 69.0f) / 12.0f) * 440.0f; return powf(2, (m - 69.0f) / 12.0f) * 440.0f;
@ -90,7 +142,7 @@ void Shifter::DetectPitch(const float* const* in, float** out, size_t size)
//DBG("frequency: " << 48000 / period << " fidel: " << fidel); //DBG("frequency: " << 48000 / period << " fidel: " << fidel);
// Adjustable filter amount (0.0f = no filtering, 1.0f = max filtering) // Adjustable filter amount (0.0f = no filtering, 1.0f = max filtering)
static float in_period_filter_amount = 0.7f; // You can expose this as a parameter static float in_period_filter_amount = 0.0f; // You can expose this as a parameter
if (fidel > 0.95) { if (fidel > 0.95) {
// Smoothly filter in_period changes // Smoothly filter in_period changes
@ -98,20 +150,11 @@ void Shifter::DetectPitch(const float* const* in, float** out, size_t size)
} }
float in_freq = 48000 / in_period; float in_freq = 48000 / in_period;
int midi = (int)(12 * log2f(in_freq / 440) + 69.5f); float midi = (12 * log2f(in_freq / 440) + 69.0f);
float target_out_period = 48000.0f / mtof(midi);
if (midi != last_autotune_midi) {
last_autotune_midi = midi;
out_period = in_period;
}
float error = target_out_period - out_period;
float adjustment = error * out_period_filter_amount;
//target_out_period = in_period * out_period_filter_amount + target_out_period * (1 - out_period_filter_amount); //target_out_period = in_period * out_period_filter_amount + target_out_period * (1 - out_period_filter_amount);
out_midi = midi; out_midi = out_midi_smoother.update(midi, (int)(midi+.5));
out_period += adjustment; out_period = 48000.0f / mtof(out_midi);
} }
void Shifter::SetRates() {} void Shifter::SetRates() {}

View File

@ -83,9 +83,9 @@ public:
void AddMidiNote(int note); void AddMidiNote(int note);
void RemoveMidiNote(int note); void RemoveMidiNote(int note);
void SetFormantPreserve(float val) { formant_preserve = val; } void SetFormantPreserve(float val) { formant_preserve = val; }
void SetAutoTuneSpeed(float val) { out_period_filter_amount = 1 - val; } void SetAutoTuneSpeed(float val);
int out_midi = -1; float out_midi = 40;
private: private:
void DetectPitch(const float* const* in, float** out, size_t size); void DetectPitch(const float* const* in, float** out, size_t size);

View File

@ -213,7 +213,7 @@ public:
autoTuneSpeed(addToLayout<AudioParameterFloat>(layout, autoTuneSpeed(addToLayout<AudioParameterFloat>(layout,
ID::autoTuneSpeed, ID::autoTuneSpeed,
"AutoTune Speed", "AutoTune Speed",
NormalisableRange<float> {0.0f, 1.0f, .01f}, NormalisableRange<float> {0.001f, 0.4f, .01f},
.5f)), .5f)),
mute(addToLayout<AudioParameterBool>(layout, ID::mute, "Mute", false)), mute(addToLayout<AudioParameterBool>(layout, ID::mute, "Mute", false)),
filterType(addToLayout<AudioParameterChoice>(layout, filterType(addToLayout<AudioParameterChoice>(layout,