better autotune speed
This commit is contained in:
@ -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() {}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user